1

I have a linting error (react-hooks/exhaustive-deps) that I am currently disabling on two lines. I understand how the code is breaking the rule, but I do not understand why this rule applies to this situation.

I want an effect to only run for cleanUp purposes when the component unmounts. I have a function, clearMessages, which is inherited from props which reset the state of a reducer back to its empty default state. It works fine when I run my project locally, but when I run the build react-scripts throws the above linting error and the build fails.

Here is a short snippet showing the effect that causes the problem.


const Search = ({ clearMessages }) => {

useEffect(() => () => clearMessages(), [])

...
...

}

This is the error message that react-scripts build throws.

Line 25: React Hook useEffect has a missing dependency: 'clearMessages'. Either include it or remove the dependency array. If 'clearMessages' changes too often, find the parent component that defines it and wrap that definition in useCallback react-hooks/exhaustive-deps

I would not expect clearMessages to change, so I am not sure why it is important that I provide it as a dependency. I do not want the effect to the only run when the value of clearMessages changes.

Dennis Vash
  • 50,196
  • 9
  • 100
  • 118
Sean San
  • 43
  • 1
  • 5
  • Possible duplicate of [How do I fix missing dependency in React Hook useEffect](https://stackoverflow.com/questions/55840294/how-do-i-fix-missing-dependency-in-react-hook-useeffect/55854902#55854902) – Shubham Khatri Jul 11 '19 at 18:08

2 Answers2

3

Along with the above answer, I found this documentation to be very helpful for reorganizing my useEffect when there is a functional dependency:

https://reactjs.org/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies

Jake Luby
  • 1,718
  • 5
  • 16
1

If clearMessages does not change, it is equivalent to an empty dependency array - [].

Either way, because "I would not expect clearMessages to change" you should use it in the dep array like the linter suggests.

const Search = ({ clearMessages }) => {

// Equivalent to an empty dependency array !if! clearMessages never change.
useEffect(() => () => clearMessages(), [clearMessages]) 

There are two phases to useEffect mentioned above:

  1. useEffect will run when clearMessages changes (if it doesn't it will run only on the component mount).
  2. By specifying a return callback, the callback will run on component unmount.

Quote from docs: When exactly does React clean up an effect? React performs the cleanup when the component unmounts.

Dennis Vash
  • 50,196
  • 9
  • 100
  • 118
  • Thanks for the response. When I read the docs for hooks, it said that if you provide a dependency, it will only call the function being returned in useEffect when that dependency changes. Would this still be called when the component unmounts even though clearMessages is still the same function? – Sean San Jul 11 '19 at 15:40