You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: React/Hooks/useEffect-basics-1.md
+27-7
Original file line number
Diff line number
Diff line change
@@ -1,5 +1,3 @@
1
-
**useEffect**
2
-
3
1
### you can think of useEffect Hook as componentDidMount, componentDidUpdate, and componentWillUnmount combined.
4
2
5
3
Mutations, subscriptions, timers, logging, and other side effects are not allowed inside the main body of a function component (referred to as React’s render phase). Doing so will lead to confusing bugs and inconsistencies in the UI. **According to doc function passed to useEffect fires after layout and paint.**
@@ -10,7 +8,7 @@ In React class components, the render method itself shouldn’t cause side effec
10
8
11
9
This is why in React classes, we put side effects into componentDidMount and componentDidUpdate.
12
10
13
-
## Effects Without Cleanup {#effects-without-cleanup}
11
+
###Effects Without Cleanup {#effects-without-cleanup}
14
12
15
13
Sometimes, we want to **run some additional code after React has updated the DOM.** Network requests, manual DOM mutations, and logging are common examples of effects that don't require a cleanup. We say that because we can run them and immediately forget about them. Let's compare how classes and Hooks let us express such side effects.
16
14
@@ -19,7 +17,7 @@ Sometimes, we want to **run some additional code after React has updated the DOM
19
17
In React class components, the `render` method itself shouldn't cause side effects. It would be too early -- we typically want to perform our effects _after_ React has updated the DOM.
20
18
This is why in React classes, we put side effects into `componentDidMount` and `componentDidUpdate`. Coming back to our example, here is a React counter class component that updates the document title right after React makes changes to the DOM:
21
19
22
-
```js{9-15}
20
+
```js
23
21
classExampleextendsReact.Component {
24
22
constructor(props) {
25
23
super(props);
@@ -48,19 +46,23 @@ class Example extends React.Component {
48
46
49
47
Note how **we have to duplicate the code between these two lifecycle methods in class.**
50
48
This is because in many cases we want to perform the same side effect regardless of whether the component just mounted, or if it has been updated. Conceptually, we want it to happen after every render -- but React class components don't have a method like this. We could extract a separate method but we would still have to call it in two places.
51
-
Now let's see how we can do the same with the `useEffect` Hook.
49
+
50
+
Now let's see how we can do the same with the `**useEffect**` Hook.
52
51
53
52
### Example Using Hooks {#example-using-hooks}
54
53
55
54
We've already seen this example at the top of this page, but let's take a closer look at it:
56
55
57
-
```js{1,6-8}
56
+
```js
58
57
importReact, { useState, useEffect } from"react";
58
+
59
59
functionExample() {
60
60
const [count, setCount] =useState(0);
61
+
61
62
useEffect(() => {
62
63
document.title=`You clicked ${count} times`;
63
64
});
65
+
64
66
return (
65
67
<div>
66
68
<p>You clicked {count} times</p>
@@ -76,4 +78,22 @@ The state and state update function come from the state hook called useState
76
78
77
79
**Why is `useEffect` called inside a component?** Placing `useEffect` inside the component lets us access the `count` state variable (or any props) right from the effect. We don't need a special API to read it -- it's already in the function scope. Hooks embrace JavaScript closures and avoid introducing React-specific APIs where JavaScript already provides a solution.
78
80
79
-
**Does `useEffect` run after every render?** Yes! By default, it runs both after the first render _and_ after every update. (We will later talk about [how to customize this](#tip-optimizing-performance-by-skipping-effects).) Instead of thinking in terms of "mounting" and "updating", you might find it easier to think that effects happen "after render". React guarantees the DOM has been updated by the time it runs the effects.
81
+
**Does `useEffect` run after every render?** Yes! By default, it runs both after the first render _and_ after every update. (We separately talk about below [how to customize this](#tip-optimizing-performance-by-skipping-effects). Instead of thinking in terms of "mounting" and "updating", you might find it easier to think that effects happen "after render". React guarantees the DOM has been updated by the time it runs the effects.
82
+
83
+
#### Great explanation of the second array argument to useEffect() - so to control when useEffect() will run
**By default, effects run after every completed render. But, you can choose to fire it only when certain values have changed, passing an array of variables as a second optional parameter.**
88
+
89
+
```js
90
+
// Without the second parameter
91
+
useEffect(() => {
92
+
console.log("I will run after every render");
93
+
});
94
+
95
+
// With the second parameter
96
+
useEffect(() => {
97
+
console.log("I will run only when valueA changes");
For each of the three most common lifecycle methods (componentDidMount, componentDidUpdate, componentWillUnmount), I will demonstrate a class style implementation
2
+
3
+
### componentDidMount
4
+
5
+
```js
6
+
// First the class component Example
7
+
classExampleextendsReact.Component {
8
+
componentDidMount() {
9
+
console.log("I am mounted!");
10
+
}
11
+
render() {
12
+
returnnull;
13
+
}
14
+
}
15
+
16
+
// With hooks the same above Example component
17
+
functionExample() {
18
+
useEffect(() =>console.log("I am mounted"), []);
19
+
returnnull;
20
+
}
21
+
```
22
+
23
+
#### The second argument is an array of values (usually props).
24
+
25
+
If any of the value in the array changes, the callback will be fired after every render.
26
+
When it's not present, the callback will always be fired after every render.
27
+
When it's an empty list, the callback will only be fired once, similar to componentDidMount.
28
+
29
+
### componentDidUpdate
30
+
31
+
```js
32
+
componentDidMount() {
33
+
console.log('mounted or updated');
34
+
}
35
+
36
+
componentDidUpdate() {
37
+
console.log('mounted or updated');
38
+
}
39
+
useEffect(() =>console.log('mounted or updated'));
40
+
```
41
+
42
+
There is not a straight forward implementation in hooks to replace componentDidUpdate. **The useEffect function can be used to trigger callbacks after every render of the component including after component mounts and component updates.**
43
+
However this is not a big problem since most of the time we place similar functions in componentDidMount and componentDidUpdate.
#### Replacing componentWillUnmount with useEffect()
2
+
3
+
```js
4
+
componentWillUnmount() {
5
+
console.log('will unmount');
6
+
}
7
+
8
+
// Now to replicate the above, just return a function inside useEffect() which will do the same job that I amd doing inside componentWillUnmount
9
+
useEffect(() => {
10
+
return () => {
11
+
console.log('will unmount');
12
+
}
13
+
}, []);
14
+
```
15
+
16
+
When you return a function in the callback passed to useEffect, the returned function will be called before the component is removed from the UI.
17
+
18
+
As we discussed previously, we need to pass an empty list as the second argument for useEffect so that the callback will only be called once. This apply to the returned function too.
19
+
20
+
Normally we do cleanups in the componentWillUnmount. Let's say you want to create an event listener on componentDidMount and clean it up on componentDidUnmount. With hooks the code will be combined into one callback function.
By the [Official doc on the above array-destructuring synatax](https://reactjs.org/docs/hooks-state.html#tip-what-do-square-brackets-mean)
9
+
By the [Official doc on the above array-destructuring syntax](https://reactjs.org/docs/hooks-state.html#tip-what-do-square-brackets-mean)
10
10
11
11
It means that we’re making two new variables **state** and **dispatch**, where **state** is set to the first value returned by **useReducer**, and **dispatch** is the second. It is equivalent to this code:
12
12
13
-
Every useReducer comes with its own dispatch function.
14
-
15
-
The **useReducer** function is tightly coupled to its reducer and its dispatch function. We dispatch action objects to that reducer only.
13
+
Every useReducer comes with its own dispatch function. The **useReducer** function is tightly coupled to its reducer and its dispatch function. We dispatch action objects to that reducer only that useReducer() function takes as its first argument.
16
14
17
15
#### Now an example to convert a useState() to a useReducer()
Copy file name to clipboardExpand all lines: React/Hooks/useState.md
+26
Original file line number
Diff line number
Diff line change
@@ -96,6 +96,32 @@ The setState it returns is almost the same used by class components—it can acc
96
96
97
97
Each call to useState is paired with a component, with its state persisting across renders. This means that you can call useState multiple times within a single function component to get multiple independent state values. Because the setState returned isn't scoped to a single component, we can define stateful behaviors independent of the component. This enables powerful new ways to abstract stateful logic.
98
98
99
+
#### When we want to display the current count in a class, we read this.state.count:
100
+
101
+
```js
102
+
<p>You clicked {this.state.count} times</p>
103
+
```
104
+
105
+
**In a function, we can use count directly:**
106
+
107
+
`<p>You clicked {count} times</p>`
108
+
109
+
#### Updating State
110
+
111
+
In a class, we need to call this.setState() to update the count state:
While useReducer with its reducer is a part of how Redux works, it isn’t Redux. The useReducer function is tightly coupled to its reducer which holds also true for its dispatch function. We dispatch action objects to that reducer only. Whereas in Redux, the dispatch function sends the action object to the store which distributes it to all its combined reducer functions. You can think of Redux as one global event bus which takes any events (actions) and processes them into a new state based on the action’s payload and the previous state.
2
+
3
+
In other words, Redux provides a global store where you can keep app data centralized. useReducer is localized to a specific component.
0 commit comments