Reputation: 1600
A page displays a list of objects [{name:, age:}, ...]
A second page allows to update the name of a particular object.
Then using hooks, how should I implement useEffect()
so the list on the front page updates only when a name change has been detected?
const [objects, setObjects] = useState([]);
useEffect(()=> {
getAllObjects()
},[getAllObjects, objects]);
Upvotes: 44
Views: 58159
Reputation: 445
// using JSON.stringify(object)
useEffect(() => {
// your code here...
}, [JSON.stringify(dependencyObject)]);
The best solution is to use JSON.stringify(object)
as it won't lead to any error on the initial load or warning about the changes in size of dependency variables.
// using spread operator
useEffect(() => {
// your code here...
}, [ ...Object.values(dependencyObject) ]);
The solution with spread operator on object keys and values will cause an error if the object is null/undefined in the initial load.
/*
Also if you make a custom function that either returns the
values or empty array then React will give a warning about
the size change in dependency array.
*/
const getDependencies = (addressType: Address) => {
if (addressType) {
return Object.values(addressType);
}
return [];
}
useEffect(() => {
// your code here...
}, [ ...getDependencies(dependencyObject) ]);
So use JSON.stringyfy(object). it won't give any errors when the object is undefined or null and React won't complain about the change in size of dependency variables.
Upvotes: 5
Reputation: 396
None of the previous answers worked for me
This is my solution:
const [objects, setObjects] = useState([]);
useEffect(()=> {
getAllObjects()
},[getAllObjects, ...Object.values(objects)]);
This way you are extracting the values from your state and once any of these values change the useEffect will be triggered
Upvotes: 1
Reputation: 2993
Please add JSON.stringify for the nested object.
useEffect(()=> {
getAllObjects()
},[getAllObjects, JSON.stringify(objects)]);
Upvotes: -5
Reputation: 7842
One can just do:
useEffect(()=> {
// do something
}, [values.name])
It's a fine solution if the object property always exists however if the property is not present at some point you get a reference error. A workaround in this scenario is to check if prop exists inside the hook
useEffect(()=> {
if (values?.name) {
// do something
}
}, [values])
Upvotes: 7
Reputation: 281774
Instead of passing the entire object to the dependency array, make sure that you only pass name. Which you can do by returning the names
const [objects, setObjects] = useState([])
useEffect(()=> {
getAllObjects()
}, [getAllObjects, ...objects.map(item => item.name)])
Upvotes: 38