Reputation: 97
useEffect
is getting triggered even though the dependency array has constant object.
I tried extracting the logic and put the object in useState
const payload = {
limit: 5,
offset: 0,
filterBy: 'All',
};
useEffect(() => {
const defaultPayload = {
limit: 10,
offset: 0,
filterBy: 'All',
};
dispatch({ type: RANDOM_CONST, payload: payload || defaultPayload });
}, [dispatch, payload]);
It should trigger only when payload
changes. Since, payload
is a constant, it should just run once and note infinite times.
Upvotes: 1
Views: 1769
Reputation: 26
You can convert the objects to JSON strings and compare them inside your useEffect hook:
JSON.stringify(oldValue) === JSON.stringify(newValue) // true
Note that object keys should have the same order:
JSON.stringify({a: 1, b: 2}) === JSON.stringify({a: 1, b: 2}) // true
JSON.stringify({a: 1, b: 2}) === JSON.stringify({b: 2, a: 1}) // false
Upvotes: 0
Reputation: 53964
There are two problems that may cause the re-render, notice that the useEffect
makes a shallow comparison with the dep-array
values:
payload
is a new object on every render, therefore oldPayload === payload
always false
, causes the useEffect
to run.
If dispatch
comes from 3rd party library (like react-redux hook), it might be making a new dispatch
reference on every render, therefore again oldDispatch === dispatch
is aways false
and causes useEffect
to run.
To fix it, you can move the "constant object" to the outer scope (which will run once), and use useCallback
hook if you passing the dispatch
.
Example from
react-redux
docs: When passing a callback using dispatch to a child component, it is recommended to memoize it withuseCallback
, since otherwise child components may render unnecessarily due to the changed reference.
const payload = {
limit: 5,
offset: 0,
filterBy: 'All'
};
const App = () => {
// v Memoize it if passing as a callback,
// check in library docs if there is a new instance
// on every render
const dispatch = useDispatch();
useEffect(() => {
dispatch({ type: RANDOM_CONST, payload });
}, []);
return;
};
Note: There is no indication in question where the
dispatch
function comes from.
Upvotes: 8