Assuming you have a hook that has multiple useState, for example:
function useMyHook() {
const [s1, setS1] = useState();
const [s2, setS2] = useState();
const setFn = useCallback(
() => {
console.log('set s1');
setS1(Date.now());
console.log('set s2');
setS2(Date.now());
},
[setS1, setS2]
);
return setFn;
}
Now, depending of WHEN you call the setFn
react will trigger either one or two rerender.
- One rerender:
function MyComponent() {
console.log('render')
const setTwoStates = useMyHook()
// sync call => triggers only one re render
useEffect(() => setTwoStates(), [])
// console.logs are: render, set s1, set s2, render
return (
<div>hello</div>
);
}
- Two rerenders:
function MyComponent() {
console.log('render')
const setTwoStates = useMyHook()
// as soon as the setFn is called in a later tick, react triggers two re renders
useEffect(() => setTimeout(setTwoStates, 1), [])
// console.logs are: render, set s1, render, set s2, render
return (
<div>hello</div>
);
}
Does anyone have an explanation for this? This can lead to unexpected behaviour depending how you call a hook.
I also created a small example repository in case you want to play around with this