I started learning to react and came across the code snippet where the function was passed as a dependency array in useEffect. I want to know the use case where such function is being passed as the dependency and why do we need to pass the function as a dependency?
4 Answers
First: This only makes sense if the code in the useEffect callback uses the function. So let's take that as a baseline. :-)
Fundamentally, you'd do that so the code in the useEffect callback is using the most up-to-date version of the function.
Here are a couple of examples where that would be important:
- The function is a prop. Since your code doesn't know why it got a new version of the function, it's important to re-run the effect with the up-to-date version of the function.
- The function uses state information it closes over (rather than using the callback form of a state setter). If you didn't re-run the effect with the updated function, the function would use stale state information. (But I wouldn't do it that way. Instead, I'd have the function use the callback form of the state setter.)
There are likely others, but they all boil down to ensuring the effect uses the most recent version of the function.
1 Comment
I am also learning React and this article helped me understand functions in the dependency array of useEffect.
Functions in dependency array of useEffect
A function is an object. It has its own identity like an object. A component re-renders each time on of its state changes. When a component re-renders, the function which is defined inside the component gets a new identity.
I made a bit clear code example here. The example from the article was unclear for me to understand. Use the console tab to see the console logs.
Comments
It depends on the use of the useEffect and the definition of the function. Basically, if you put a function inside a useEffect array, each time the function will change, or more accurately, it's reference, your effect will be called again, with the new function reference.
This is good in case you want to always use the latest function, but it can also be tricky. If the passed function is defined inside a component, it means that on every component render the function will be redefined, meaning your effect will be called on each component render. It can be heavy sometimes, depends on what your effect does.
It can still be avoided though, if the component in which the function is defined is using useCallback in order to memoize the function. This way, the function will have its own dependencies array, and will only be redefined (and change reference) when you decide it's needed.
Comments
I have a good use case where the function current() returns the current language code, which is a function defined in another utils module, not a inline function defined the React component itself
useEffect(() => {
setTimeout(() => setButtonText('TXT_BUTTON_SEARCH_ANON'), 20000)
}, [current()])
I did get such a error from Console:
Warning: The final argument passed to useEffect changed size between renders. The order and size of this array must remain constant.
Previous: [no] Incoming: [no, function () { setTimeout(function () { return setButtonText('TXT_BUTTON_SEARCH_ANON'); }, 20000); }, 0] at IntroStep