首页 > 解决方案 > Mutate multiple states from within useEffect causes react-hooks/exhaustive-deps warning

问题描述

I am playing around with React Hooks. When the button is clicked, I want to increment a counter. After the counter was incremented, the application should not allow further increments until clicked is reset to false.

I came up with this:

function App() {
  const [counter, setCounter] = useState(0);
  const [clicked, setClicked] = useState(false);

  useEffect(() => {
    if (clicked) {
      setCounter(counter + 1);
      setTimeout(() => {
        setClicked(false);
      }, 2000);
    }
  }, [clicked]);

  return (
    <div className="App">
      <p>Clicked: {String(clicked)}</p>
      <p>Counter: {counter}</p>
      <button type="button" onClick={() => setClicked(true)}>
        Click me
      </button>
    </div>
  );
}

It actually works. However React is complaining with following warning:

React Hook useEffect has a missing dependency: 'counter'. Either include it or remove the dependency array. You can also do a functional update 'setCounter(c => ...)' if you only need 'counter' in the 'setCounter' call. (react-hooks/exhaustive-deps)

When I add the counter to the dependencies, useEffect will get into an infinite loop, because clicked is true and setCounter was called from within useEffect.

I want the counter only to be incremented, when clicked changed from false to true. That works if the dependency list only contains clicked, but React complains about that.

Try out for yourself: https://codesandbox.io/s/dreamy-shadow-7xesm

标签: reactjs

解决方案


尝试将 setCounter(counter + 1) 替换为:

setCounter(counter => counter + 1)

就像警告说的那样。应该解决。


推荐阅读