Reputation: 3240
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!
Upvotes: 4
Views: 1742
Reputation: 281646
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
Upvotes: 4