TransWikia.com

React useEffect warning to put missing dependency. But dependency value changes in the hook

Stack Overflow Asked by dracarys on December 11, 2021

I want to change the value of formStepTouched when the value for step changes, so I am using useEffect. But useEffect throws a warning that its missing dependency of formStepTouched. As that is the value that’s changing, putting that in the dependency array would cause infinite calls.

 const [step, setStep] = useState(0);
 const [formStepTouched, setFormStepTouched] = useState(
    Array(childrenArray.length)
      .fill(false)
      .map((_, idx) => idx === 0)
 )

 useEffect(() => {
    const newFormStepTouched = [...formStepTouched];
    newFormStepTouched[step] = true;
    setFormStepTouched(newFormStepTouched);
  }, [step]);

Please refer to the codesandbox link below:
https://codesandbox.io/s/brave-gould-ymjt0?file=/src/App.js

As you can see the demo works perfectly however an error message is shown. If the dependecy is added useEffect will be called infinitely.

How to get rid of the error message.

2 Answers

You can pass a callback to state setter:

const { useEffect, useState } = React;

const App = () => {
  const [step, setStep] = useState(0);
  const [formStepTouched, setFormStepTouched] = useState(
    Array(5)
      .fill(false)
      .map((_, idx) => idx === 0)
  );

  useEffect(() => {
    //pass a callback to state setter
    setFormStepTouched((formStepTouched) => {
      if (formStepTouched[step] === true) {
        //nothing to change
        return formStepTouched;
      }
      return formStepTouched.map((s, i) =>
        i === step ? true : s
      );
    });
  }, [step]);

  return (
    <div>
      <button onClick={() => setStep(step + 1)}>
        nex step
      </button>
      <div>
        <pre>
          {JSON.stringify(formStepTouched, undefined, 2)}
        </pre>
      </div>
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Answered by HMR on December 11, 2021

   useEffect(() => {
    setFormStepTouched(prevState =>  {
      const newFormStepTouched = [...prevState]
      newFormStepTouched[step] = true
      return newFormStepTouched
    });
  }, [step]);

The linter is telling you that have an external dependency that may change, you can read more here

Answered by K.P on December 11, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP