はじめに
仕事でReactを使うようになってuseEffect
を使うことがありました。
まだなんとなくでしか理解できていないので、試してみたいと思います。
useEffectとは
Reactのライフサイクルの中で、componentDidMount
やcomponentDidUpdate
などのタイミングで処理を実行するためのフックです。
ライフサイクルってなに?
Reactのコンポーネントは、マウント、アップデート、アンマウントの3つのフェーズを通過します。
それぞれのフェーズで、コンポーネントに対して処理を実行することができます。
マウントのフェーズの中には、コンポーネントがDOMに追加されたときに実行されるcomponentDidMount
があります。
アップデートのフェーズの中には、コンポーネントが更新されたときに実行されるcomponentDidUpdate
があります。
このタイミングでuseEffectが実行されます。
useEffectを使ってみる
import "./styles.css";
import React, { useState, useEffect } from "react";
export default function App() {
const [count, setCount] = useState(0);
useEffect(() => {
if (count < 100000) {
setCount((c) => c + 1);
}
}, [count]);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<div>
<div>Count: {count}</div>
</div>
</div>
);
}
-
useEffect
の第2引数にcountを渡しています。- countが変更されたときに
useEffect
が実行されます。 -
useEffect
の中でsetCount
を実行しているので、またコンポーネントが更新されます。- 無限ループの完成です。
- countが変更されたときに
余談
- アップデーター関数を使っているのは、正しくカウントアップされるようにするためです。
-
setCount(count + 1)
とすると、count
の値が更新される前にsetCount
が実行されてしまうため、正しくカウントアップされません。 - https://react.dev/reference/react/useState#updating-state-based-on-the-previous-state
-
Chrome DevToolsで確認する
コンソールのところに以下のようなエラーが表示されます。
上部にあるcodesandbox
のconsole
でも確認できます
Warning: Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.
翻訳すると以下のようになります。
警告 最大更新深度を超えました。これは、コンポーネントがuseEffectの内部でsetStateを呼び出したが、useEffectが依存関係の配列を持っていないか、レンダリングごとに依存関係の1つが変更された場合に発生する可能性があります。
終わりに
useEffect
を使って無限ループを作ることができました。
今回の無限ループを止めるなら、useEffect
の第2引数を空にすることで、マウント時・アンマウント時のみ実行されるようになります。
もっと詳しくなりたいので、勉強していきたいと思います。
これを読むをいいらしいので、読んでみます。
Reactが楽しくなってきました