If we have a function that fetches user data as such:
const fetchUserData = () => { /* code here */ }
And then we have a useEffect with an empty array so it runs once after the component has rendered:
useEffect(() => { fetchUserData(); }, []);
Then eslint/tslint throws this warning:
React Hook useEffect has a missing dependency: 'fetchUserData'. Either include it or remove the dependency array.
I get that this is good practice if say our function variable was a let
or var
but how would the fetchUserData
variable change if it’s declared with a const
keyword.
Is this an error on the linter and we should just ignore it or is there something that I’m missing?
Advertisement
Answer
Whether the “variable”¹ referring the function is let
, var
, or const
is irrelevant. Remember that every time your component needs to be rendered, your component function gets called again, which creates an entirely new execution context with its own const
(or let
or var
) “variable” with a new fetchUserData
function assigned to it. useEffect
will only ever call the first one of those that’s created (because you have a []
dependency array). For this specific situation it may be harmless, but in the general case you run the risk of having closures over stale data, hence the linter warning.
If you don’t use any state or props in fetchUserData
, you can relocate it inside the useEffect
callback, which both gets rid of the error and avoids recreating a function on every render that you’re not going to use. (If you do use state or props in fetchUserData
, it probably shouldn’t only be called once when the component is mounted, but each time the state/props it uses changes.)
¹ More generally, binding (a binding of a name to a storage slot containing a value in the lexical environment object for the execution context of the function call).