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
### [What is Shallow Comparison from Official dox](https://reactjs.org/docs/shallow-compare.html)
2
2
3
-
- A> When shallow comparing scalar values (numbers, strings) it compares their values. When comparing objects, it does not compare their attributes - only their references are compared (e.g. "do they point to same object?).
3
+
-A> When shallow comparing scalar values (numbers, strings) it compares their values. When comparing objects, it does not compare their attributes - only their references are compared (e.g. "do they point to same object?).
4
4
5
-
- B> Shallow comparison is when the properties of the objects being compared is done using "===" or strict equality and will not conduct comparisons deeper into the properties. So if you shallow compare a deep nested object it will just check the reference not the values inside that object.
5
+
-B> Shallow comparison is when the properties of the objects being compared is done using "===" or strict equality and will not conduct comparisons deeper into the properties. So if you shallow compare a deep nested object it will just check the reference not the values inside that object.
6
6
7
-
- C> shallowCompare performs a shallow equality check on the current props and nextProps objects as well as the current state and nextState objects.
8
-
It does this by iterating on the keys of the objects being compared and returning true (i.e. the component SHOULD GET UPDATED ) when the values of a key in each object are not strictly equal.
7
+
-C> shallowCompare performs a shallow equality check on the current props and nextProps objects as well as the current state and nextState objects.
8
+
It does this by iterating on the keys of the objects being compared and returning true (i.e. the component SHOULD GET UPDATED ) when the values of a key in each object are not strictly equal.
9
9
10
-
shallowCompare returns true if the shallow comparison for props or state fails and therefore the component should update.
11
-
shallowCompare returns false if the shallow comparison for props and state both pass and therefore the component does not need to update.
12
-
.
10
+
shallowCompare returns true if the shallow comparison for props or state fails and therefore the component should update.
11
+
shallowCompare returns false if the shallow comparison for props and state both pass and therefore the component does not need to update.
12
+
.
13
13
14
14
#### useEffect and shallow comparison
15
15
@@ -21,7 +21,48 @@ useEffect‘s primary goal is to encompass any side effect you might want to use
21
21
22
22
Important features useEffect skips running the effect when things don’t change. You don’t actually have to use the dependency values in the effect. You can pass in a prop value as a dependency.
23
23
24
+
### Now how does shallow comparison works in React
25
+
26
+
Shallow compare does check for equality. When comparing scalar values (numbers, strings) it compares their values. When comparing objects, it does not compare their's attributes - only their references are compared (e.g. "do they point to same object in memory ?).
27
+
28
+
Let's consider following shape of user object
29
+
30
+
```js
31
+
user = {
32
+
name:"John",
33
+
surname:"Doe"
34
+
};
35
+
```
36
+
37
+
**Example 1:**
38
+
39
+
```js
40
+
constuser=this.state.user;
41
+
user.name="Jane";
42
+
43
+
console.log(user ===this.state.user); // true
44
+
```
45
+
46
+
Notice you changed users name. Even with this change objects are equal. They references are exactly same. Meaning no change and no re-render
47
+
48
+
**Example 2:**
49
+
50
+
```js
51
+
constuser=clone(this.state.user);
52
+
console.log(user ===this.state.user); // false
53
+
```
54
+
55
+
Now, without any changes to object properties they are completely different. By cloning original object you create new copy, with different reference.
56
+
57
+
And the clone function might look as this (ES6 syntax)
58
+
59
+
`const clone = obj => Object.assign({}, ...obj);`
60
+
61
+
Shallow compare is efficient way to detect changes. It expect you don't mutate data.
62
+
63
+
`shallowCompare()` function in React actually works like this (just what the official doc says above) - iterating on the keys of the objects being compared and returning true (i.e. saying that the objects are different meaning a re-render is necessary ) when the values of a key in each object are not strictly equal.
From [React official guide](https://reactjs.org/docs/hooks-reference.html#functional-updates)
2
+
3
+
Unlike the setState method found in class components, useState does not automatically merge update objects. You can replicate this behavior by combining the function updater form with object spread syntax:
4
+
5
+
```js
6
+
setState(prevState=> {
7
+
// Object.assign would also work
8
+
return { ...prevState, ...updatedValues };
9
+
});
10
+
```
11
+
12
+
Another option is useReducer, which is more suited for managing state objects that contain multiple sub-values.
13
+
14
+
The key point and guidance to update states
15
+
16
+
Just as with setState in a class component you need to be careful when updating state derived from something that already is in state. State updates using hooks are also batched and hence whenever you want to update state based on previous one its better to use the callback pattern.
17
+
18
+
If you e.g. update a count twice in a row, it will not work as expected if you don't use the function version of updating the state.
19
+
20
+
```js
21
+
const { useState } = React;
22
+
23
+
functionApp() {
24
+
const [count, setCount] =useState(0);
25
+
26
+
// This will be bad, might lead to more bugs because such code often end up inside a closure which has an outdated value of myState.
27
+
functionbrokenIncrement() {
28
+
setCount(count +1);
29
+
setCount(count +1);
30
+
}
31
+
32
+
// The recommended way is to use a function to update the state
Copy file name to clipboardExpand all lines: React/Hooks/useEffect-basics-1.md
+8
Original file line number
Diff line number
Diff line change
@@ -97,3 +97,11 @@ useEffect(() => {
97
97
console.log("I will run only when valueA changes");
98
98
}, [valueA]);
99
99
```
100
+
101
+
**The reason we need to pass in an empty array as the second argument to useEffect** -
102
+
103
+
In order to register just once we need to pass in an empty array as the second argument to useEffect.
104
+
105
+
This (passing the empty array) typically is used to control whether or not the useEffect needs to be re-applied. This array is diffed from the original creation of the effect and the new one being passed in. It will diff the array (just like it does the virtual DOM) and decide if it needs to re-apply the effect.
106
+
107
+
Passing in an empty array tells React to diff, however there is nothing different between each render so the effect will only be run once. Be aware though, if you are calling a function from props, or relying on props inside the effect you will need to pass them into the array to re-apply the effect.
Copy file name to clipboardExpand all lines: React/Hooks/useEffect-running-callback-after-setState-IMPORTANT.md
+4-1
Original file line number
Diff line number
Diff line change
@@ -75,7 +75,7 @@ useEffect hooks takes the second parameter as an array of values which React nee
75
75
```js
76
76
const [loading, setLoading] =useState(false);
77
77
78
-
...
78
+
....
79
79
80
80
useEffect(() => {
81
81
doSomething(); // This is be executed when `loading` state changes
@@ -140,3 +140,6 @@ const getNextPage = () => {
140
140
setIsLoading(true);
141
141
};
142
142
```
143
+
144
+
So now the question is - in the case of having multiple **setStates** that we want to wait for, we need multiple **useEffect** hooks.
145
+
If you want to take different actions when different states change then yes, we need multiple useEffect() hooks, but if you want to do the sme thing on any of those multiple states change, then you could pass multiple arguments like [isLoading, isUpdated, showError]
Copy file name to clipboardExpand all lines: React/Hooks/useState-replace-componentWillReceiveProps-getDerivedStateFromProps.md
+1-3
Original file line number
Diff line number
Diff line change
@@ -34,7 +34,7 @@ const Message = () => {
34
34
35
35
**The initial value will be assigned only on the initial render (if it’s a function, it will be executed only on the initial render).**
36
36
37
-
**In subsequent renders (due to a change of state in the component or a parent component), the argument of the useState hook will be ignored and the current value will be retrieved. It is important to keep this in mind because, for example, if you want to update the state based on the new properties the component receives:**
37
+
**In subsequent renders (due to a change of state in the component or a parent component), the argument of the useState hook will be ignored and the current value of the state will be retrieved. It is important to keep this in mind because, for example, if you want to update the state based on the new properties the component receives:**
Pere [Hooks Official Docs](https://reactjs.org/docs/hooks-reference.html) - **During the initial render, the returned state (state) is the same as the value passed as the first argument (initialState). During subsequent re-renders (i.e. after invoking a setState (like setCount or whatever) inside useEffect()), the first value returned by useState will always be, whatever is the most recent state after applying updates.**
92
92
93
-
**useState** takes an initial state as an argument, and returns the current state and an updater function.
94
-
95
93
The setState it returns is almost the same used by class components—it can accept a callback that gets the current state as an argument, but it doesn't automatically merge top-level object keys.
96
94
97
95
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.
0 commit comments