Sean San
Sean San

Reputation: 53

How to fix a react-hooks/exhaustive-deps linting error with no dependency

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.

Upvotes: 2

Views: 5257

Answers (2)

Jake Luby
Jake Luby

Reputation: 1758

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

Upvotes: 3

Dennis Vash
Dennis Vash

Reputation: 53884

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.

Upvotes: 1

Related Questions