React hook useEffect 永远持续运行/无限循环

IT技术 javascript reactjs react-hooks
2021-04-09 01:12:05

我正在尝试新的React HooksuseEffectAPI,它似乎在无限循环中永远运行!我只希望回调useEffect运行一次。这是我的代码供参考:

单击“运行代码片段”以查看“Run useEffect”字符串被无限打印到控制台。

function Counter() {
  const [count, setCount] = React.useState(0);

  React.useEffect(() => {
    console.log('Run useEffect');
    setCount(100);
  });

  return (
    <div>
      <p>Count: {count}</p>
    </div>
  );
}

ReactDOM.render(<Counter />, document.querySelector('#app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>

<div id="app"></div>

1个回答

发生这种情况是因为useEffect在每次渲染后触发,Counter()在这种情况下是功能组件函数调用当你做一个setX从返回的呼叫useStateuseEffect,阵营将再次呈现该组件,并且useEffect将再次运行。这会导致无限循环:

Counter()useEffect()setCount()Counter()useEffect()→ ...(循环)

为了让你useEffect只运行一次,传递一个空数组[]作为第二个参数,如下面的修改片段所示。

第二个参数的目的是在数组参数中的任何值发生更改时告诉 React:

useEffect(() => {
  setCount(100);
}, [count]); // Only re-run the effect if count changes

您可以将任意数量的值传递到数组中,并且useEffect只有在任何一个值发生更改时才会运行。通过传入一个空数组,我们告诉 React 不要跟踪任何更改,只运行一次,有效地模拟componentDidMount.

function Counter() {
  const [count, setCount] = React.useState(0);

  React.useEffect(() => {
    console.log('Run useEffect');
    setCount(100);
  }, []);

  return (
    <div>
      <p>Count: {count}</p>
    </div>
  );
}

ReactDOM.render(<Counter />, document.querySelector('#app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>

<div id="app"></div>

阅读有关useEffect 的更多信息

这是解决方案,但是如果您使用的是react-hookseslint 插件。这将被exhaustive-deps规则标记看起来正确的解决方案是使用useCallback钩子,更多讨论在这里:github.com/facebook/react/issues/14920#issuecomment-471070149
2021-06-12 01:12:05