So I thought I was getting the hang of these hooks, but the lint rule react-hooks/exhaustive-deps
is tripping me up.
I have this method inside my Provider
const onScreenChange = useCallback(
(key, value) => {
const newState = Object.assign({}, screenState, { [key]: value });
localStorage.setItem('screens', JSON.stringify(newState));
setScreenState(newState);
},
[]); // screenState
I'm allowing the rest of my app to access this by passing it into the value prop...
return <Provider value={{onScreenChange, ... }}>children</Provider>
And then I'm calling this method from a child component when the route changes
useEffect(() => {
if (match.path === `/${screenKey}`) {
onScreenChange(screenKey, 'external');
}
}, [onScreenChange, match.path, screenKey]);
The above code works exactly how I want, and I can't see this causing any bugs. However eslint is telling me:
React Hook useCallback has a missing dependency: 'screenState'. Either include it or remove the dependency array
When I add screenState
into the array, it causes an infinite loop as soon as the onScreenChange
method is called.
It's pretty obvious why the loop is now happening, but how do I stop this and "follow the rules"?
Thanks in advance for any help!
The warning from eslint seems to be correct. Since screenState value won't be updated correctly if the onScreenChange
method is called multiple times. You must provide screenState
as a depedency to useCallback
const onScreenChange = useCallback(
(key, value) => {
const newState = Object.assign({}, screenState, { [key]: value });
localStorage.setItem('screens', JSON.stringify(newState));
setScreenState(newState);
},
[screenState]);
The other way to write the same code without adding the deps is to make use of state updater callback pattern
const onScreenChange = useCallback(
(key, value) => {
setScreenState(oldState => {
const newState = Object.assign({}, oldState, { [key]: value });
localStorage.setItem('screens', JSON.stringify(newState));
return newState;
});
},
[]);
However you may choose to disable the deps warning if you are absolutely sure what you are trying to do is correct.
You may read below post for more inforamtion:
How do I fix missing dependency in React Hook useEffect
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With