According to the react docs at https://reactjs.org/docs/hooks-reference.html#conditionally-firing-an-effect when using the useEffect dependency array, you are supposed to pass in all the values used inside the effect.
If you use this optimization, make sure the array includes all values from the component scope (such as props and state) that change over time and that are used by the effect. Otherwise, your code will reference stale values from previous renders. Learn more about how to deal with functions and what to do when the array values change too often.
I don't know how the hook works behind the scenes, so I'm going to guess here. Since the variables inside the closure might go stale, that would imply that the function is cached somewhere. But why would you cache the function since its not being called unless the dependencies changed and the function needs to be recreated anyways?
I've made a small test component.
function App() {
const [a, setA] = useState(0);
const [b, setB] = useState(0);
useEffect(() => {
console.log("b", b);
}, [a]);
return (
<div>
<div>App {a}</div>
<button
onClick={() => {
setA(a + 1);
}}
>
AddA
</button>
<button
onClick={() => {
setB(b + 1);
}}
>
AddB
</button>
</div>
);
}
You can try it out here: https://codesandbox.io/s/react-hooks-playground-forked-m5se8 and it works just fine, with no stale values. Can someone please explain what I'm missing?
Edit: After feedback that my question is not entirely clear, adding a more specific question:
When after a page load I click on AddB button and then click on AddA button, value displayed in console is 1. According to the docs, I should get a stale value (0). Why is this not the case?