新しい React Hooks のuseEffect
APIを試してみましたが、無限ループで永遠に実行し続けているようです! 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>
これは、レンダリングのたびにuseEffect
がトリガーされるためです。これは、この場合ステートレス機能コンポーネントのCounter()
関数の呼び出しです。 setX
でuseState
から返される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 の詳細をお読みください。