I’m trying to update a state calling its setState method from an useEffect, but it’s updating only on the render and the first call to the setState method.
const [filterChanged, setFilterChanged] = useState(false);
useEffect(() => {
console.log('filterChanged UPDATED', filterChanged);
}, [filterChanged]);
useEffect(() => {
const sessionFilter = sessionStorage.getItem('test-filter');
if (sessionFilter === props.selectedFilter) {
console.log('filter not changed');
setFilterChanged(false);
} else {
console.log('filter changed');
setFilterChanged(true);
}
sessionStorage.setItem('test-filter', props.selectedFilter);
}, [props.selectedFilter]);
I left the console.logs because I can see in the console the filter changed
messages but not the updated ones.
I know this is asyncronous but the filterChanged
dependant useEffect is not being triggered even a while after calling the setFilterChanged
method.
2
Answers
The
first useEffect
executes twice: initially during the first render, and again whensetFilterChanged(true)
is called.However, if you select the same category, the
second useEffect
will not execute because the variables in its dependency array do not change. This meansfilterChanged
will remain true.Instead of writing
setFilterChanged(true)
, you can writesetFilterChanged(!filterChanged)
.If the filter does not change, neither of the
useEffect
hooks will execute.Please do not allow the component to retain the value of the state filterChanged. You can reset the state with a key. The sample code below does the same. Please also see the Test run enclosed as well.
App.js
Test run
On load of the App
On clicking the button first time