Search code examples
dependencieseslintuse-effectuse-state

Avoiding ESLint 'react-hooks/exhaustive-deps' warnings with useEffect & useState


I'm using a useEffect() hook to update some state via a 'useState' call:

useEffect(
  () => {
    const newProps = {}

    departments.forEach(dept => {
      const { code } = dept
      const newCode = code.toLowerCase()
      newProps[newCode + '_reviewer'] = ''
    })

    setFormValues({ ...formValues, ...newProps })
  },
  [departments]
)

ESLint gives me, unsurprisingly a warning re formValues:

React Hook useEffect has a missing dependency: 'formValues'. 

However, it goes on to mention:

Either include it or remove the dependency array.
You can also do a functional update 'setFormValues(f => ...)'
if you only need 'formValues' in the 'setFormValues' call

react-hooks/exhaustive-deps

I'm intrigued by the mysterious 'setFormValues(f => ...)' approach. What exactly does this mean? How should I be re-writing setFormValues({ ...formValues, ...newProps }) in order to avoind the ESLint warning, without adding formValues as a dependency or adding a // eslint-disable-next-line react-hooks/exhaustive-deps ?

I've tried looking at the repo, and the closest I got to was this, which didn't seem to mention this particular work around.


Solution

  • You can pass a function to the set function that has as first param the current value of that state, and sets that state to what you return in that function.

    So you can instead do:

    setFormValues(fValues => ({...fValues, ...newProps}));
    

    And as you don;t use the formValues state anywhere on the useEffect you can avoid adding it to the deps array