web-dev-qa-db-ja.com

ReactフックuseEffectは永遠に継続的に実行される/無限ループ

新しい React HooksuseEffect AP​​Iを試してみましたが、無限ループで永遠に実行し続けているようです! useEffectのコールバックを1回だけ実行したい。参照用の私のコードは次のとおりです。

「Run code snippet」をクリックして、「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/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>

<div id="app"></div>
17
Yangshun Tay

これは、レンダリングのたびにuseEffectがトリガーされるためです。これは、この場合ステートレス機能コンポーネントのCounter()関数の呼び出しです。 setXuseStateから返されるuseEffect呼び出しを行うと、Reactはそのコンポーネントを再びレンダリングし、useEffectが再び実行され、これにより無限ループが発生します。

Counter()useEffect()setCount()Counter()useEffect()→...(ループ)

useEffectを1回だけ実行するには、以下の改訂されたスニペットに示すように、空の配列[]を2番目の引数として渡します。

2番目の引数の目的は、配列引数の値のいずれかが変更されたときにReactを伝えることです。

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

任意の数の値を配列に渡すことができ、useEffectはいずれかの値が変更されたときにのみ実行されます。空の配列を渡すことにより、React変更を追跡せず、1回だけ実行し、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/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>

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

seEffect の詳細をお読みください。

27
Yangshun Tay