Skip to content

Commit 1d4d077

Browse files
committed
Initial commit
0 parents  commit 1d4d077

File tree

15 files changed

+16669
-0
lines changed

15 files changed

+16669
-0
lines changed

.gitignore

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.js
7+
8+
# testing
9+
/coverage
10+
11+
# production
12+
/build
13+
14+
# misc
15+
.DS_Store
16+
.env.local
17+
.env.development.local
18+
.env.test.local
19+
.env.production.local
20+
21+
npm-debug.log*
22+
yarn-debug.log*
23+
yarn-error.log*
24+
25+
# Learn-specific .results.json
26+
.results.json
27+
28+
# Ignore ESLint files
29+
.eslintcache

.learn

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
tags:
2+
- bundler
3+
- introduction
4+
languages:
5+
- react
6+
resources: 2

README.md

Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
# React Side Effects
2+
3+
## Overview
4+
5+
We'll talk about how to use side-effects in our function components with the
6+
`useEffect` hook, and how to get additional functionality in our components
7+
beyond just returning JSX elements.
8+
9+
## Objectives
10+
11+
1. Understand side effects in programming
12+
2. Use the `useEffect` hook to write side effects in components
13+
3. Control when the side effects run by using a dependencies array with `useEffect`
14+
15+
## Side Effects
16+
17+
When you hear about side effects in terms of pharmaceuticals, they're often not
18+
something to get too excited about (typically, you'd take some aspirin for its
19+
_main effect_ of making a headache go away instead of its _side effect_ of nausea).
20+
21+
In terms of _programming_, a side effect is defined as:
22+
23+
> an operation, function or expression is said to have a side effect if it
24+
> modifies some state variable value(s) outside its local environment, that is
25+
> to say has an observable effect besides returning a value (the main effect) to
26+
> the invoker of the operation. -- [Wikipedia on Side Effects][side-effects]
27+
28+
Put more simply, if we call a function and that function causes change in our
29+
application _outside of the function itself_, it's considered to have caused a
30+
_side effect_. Things like making _network requests_, accessing data from a
31+
database, writing to the file system, etc. are common examples of side effects
32+
in programming.
33+
34+
In terms of a React component, the _main effect_ of the component is to return
35+
some JSX. That's been true of all of the components we've been working with! One
36+
of the first rules we learned about function components is that they take in
37+
props, and return JSX.
38+
39+
_However_, it's often necessary for a component to perform some _side effects_
40+
in addition to its main job of returning JSX. For example, we might want to:
41+
42+
- Fetch some data from an API when a component loads
43+
- Start or stop a timer
44+
- Manually change the DOM
45+
- Get the user's location
46+
47+
In order to handle these kinds of side effects within our components, we'll need
48+
to use another special **hook** from React: `useEffect`.
49+
50+
## The useEffect Hook
51+
52+
To use the `useEffect` hook, we must first import it:
53+
54+
```js
55+
import React, { useEffect } from "react";
56+
```
57+
58+
Then, inside our component, we call `useEffect` and pass in a callback function
59+
to run as a _side effect_:
60+
61+
```js
62+
function App() {
63+
useEffect(
64+
// side effect function
65+
() => {
66+
console.log("useEffect called");
67+
}
68+
);
69+
70+
console.log("Component rendering");
71+
72+
return (
73+
<div>
74+
<button>Click Me</button>
75+
<input type="text" placeholder="Type away..." />
76+
</div>;
77+
)
78+
}
79+
```
80+
81+
If you run the example code now, you'll see the console messages appear in this
82+
order:
83+
84+
- Component rendering
85+
- useEffect called
86+
87+
So we are now able to run some extra code as a _side effect_ any time our
88+
component is rendered.
89+
90+
> By using this Hook, you tell React that your component needs to do something
91+
> after render. React will remember the function you passed (we’ll refer to it
92+
> as our “effect”), and call it later after performing the DOM updates. --
93+
> [useEffect hook][useeffect-hook]
94+
95+
Let's add some state into the equation, and see how that interacts with our
96+
`useEffect` hook.
97+
98+
```js
99+
function App() {
100+
const [count, setCount] = useState(0);
101+
const [text, setText] = useState("");
102+
103+
useEffect(() => {
104+
console.log("useEffect called");
105+
});
106+
107+
console.log("Component rendering");
108+
109+
return (
110+
<div>
111+
<button onClick={() => setCount((count) => count + 1)}>
112+
I've been clicked {count} times
113+
</button>
114+
<input
115+
type="text"
116+
placeholder="Type away..."
117+
value={text}
118+
onChange={(e) => setText(e.target.value)}
119+
/>
120+
</div>
121+
);
122+
}
123+
```
124+
125+
Try clicking the button or typing in the input field to trigger updates in
126+
state. Every time state is set, we should also see those same two console
127+
messages in the same order:
128+
129+
- Component rendering
130+
- useEffect called
131+
132+
**By default, `useEffect` will run our side effect function every time the
133+
component re-renders**. However, sometimes we only want to run our side effect
134+
once. For example -- imagine we're using the `useEffect` hook to fetch some data
135+
from an external API (a common use case for `useEffect`). How can we control
136+
when `useEffect` will run our side effect function?
137+
138+
## useEffect Dependencies
139+
140+
React gives us a way to control when the side effect will run, by passing a
141+
second argument to `useEffect` of a _dependencies array_. It looks like this:
142+
143+
```js
144+
useEffect(
145+
// 1st arg: side effect (callback function)
146+
() => console.log("useEffect called"),
147+
// 2nd arg: dependencies array
148+
[count]
149+
);
150+
```
151+
152+
Update the `useEffect` function as above and try running the code again. Now,
153+
the side effect will only run when the `count` variable changes. We won't see
154+
any console messages from `useEffect` when typing in the input -- we'll only see
155+
them when clicking the button!
156+
157+
We can also pass in an _empty_ array of dependencies as a second argument, like
158+
this:
159+
160+
```js
161+
useEffect(() => {
162+
console.log("useEffect called");
163+
}, []); // second argument is an empty array
164+
```
165+
166+
Now, the side effect will only run the _first time_ our component renders! Keep
167+
this trick in mind -- we'll be using it again soon to work with fetching data.
168+
169+
## Performing Side Effects
170+
171+
Running a `console.log` isn't the most interesting side effect, so let's try a
172+
couple other examples.
173+
174+
One kind of side effect we can demonstrate here is _updating parts of the
175+
webpage page outside of the React DOM tree_. React is responsible for all the
176+
DOM elements rendered by our components, but there are some parts of the webpage
177+
that live outside of this tree. Take, for instance, the `<title>` of our page --
178+
this is what shows up in the browser tab, like this:
179+
180+
![title](images/title.png)
181+
182+
Updating this part of the page would be considered a _side effect_, so let's use
183+
`useEffect` to update it!
184+
185+
```js
186+
useEffect(() => {
187+
document.title = text;
188+
}, [text]);
189+
```
190+
191+
Here, what we're telling React is:
192+
193+
"Hey React! When my App component renders, I also want you to update the
194+
document's title. But you should only do that when the `text` variable changes."
195+
196+
Let's add another side effect, this time running a `setTimeout` function. We
197+
want this function to _reset_ the `count` variable back to 0 after 5 seconds.
198+
Running a `setTimeout` is another example of a side effect, so once again, let's
199+
use `useEffect`:
200+
201+
```js
202+
useEffect(() => {
203+
setTimeout(() => setCount(0), 5000);
204+
}, []);
205+
```
206+
207+
With this side effect, we're telling React:
208+
209+
"Hey React! When my App component renders, I also want you to set this timeout
210+
function. In 5 seconds, you should update state and set the count back to 0. You
211+
should only set this timeout function once, I don't want a bunch of timeouts
212+
running every time my component updates. kthxbye!"
213+
214+
All together, here's what our updated component looks like:
215+
216+
```js
217+
function App() {
218+
const [count, setCount] = useState(0);
219+
const [text, setText] = useState("");
220+
221+
useEffect(() => {
222+
document.title = text;
223+
}, [text]);
224+
225+
useEffect(() => {
226+
setTimeout(() => setCount(0), 5000);
227+
}, []);
228+
229+
console.log("Component rendering");
230+
231+
return (
232+
<div>
233+
<button onClick={() => setCount((count) => count + 1)}>
234+
I've been clicked {count} times
235+
</button>
236+
<input
237+
type="text"
238+
placeholder="Type away..."
239+
value={text}
240+
onChange={(e) => setText(e.target.value)}
241+
/>
242+
</div>
243+
);
244+
}
245+
```
246+
247+
Explore this code to familiarize yourself with `useEffect`, and see what changes
248+
by changing the dependencies array. It's also a good idea to add some console
249+
messages or put in a debugger to see what exactly when the side effects will
250+
run.
251+
252+
## Conclusion
253+
254+
So far, we've been working with components solely for rendering to the DOM based
255+
on JSX, and updating based on changes to state. It's also useful to introduce
256+
_side effects_ to our components so that we can interact with the world outside
257+
of the React DOM tree and do things like making network requests or setting
258+
timers.
259+
260+
In the next lessons, we'll see some more practical uses for `useEffect` and get
261+
practice handling network requests from our components.
262+
263+
## Resources
264+
265+
- [React Docs on useEffect][useeffect-hook]
266+
- [A Complete Guide to useEffect](https://overreacted.io/a-complete-guide-to-useeffect/)
267+
268+
[side-effects]: https://en.wikipedia.org/wiki/Side_effect_(computer_science)#:~:text=In%20computer%20science%2C%20an%20operation,the%20invoker%20of%20the%20operation.
269+
[useeffect-hook]: https://reactjs.org/docs/hooks-effect.html

images/title.png

14.5 KB
Loading

jsconfig.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"typeAcquisition": {
3+
"include": ["jest"]
4+
}
5+
}

0 commit comments

Comments
 (0)