そもそもuseEffectとは?
useEffect は、Reactにおけるフック(Hook)の一つです。主に「副作用」を扱うために使われます。副作用とは、データのフェッチや、DOMの操作、外部APIとの通信など、コンポーネントの描画プロセスに直接影響しない処理を指します。
主なユースケース
useEffect が使用される典型的なユースケースは以下の通りです。
外部APIでのデータ通信(fetchなど)
DOMの直接操作(例:スクロール位置の変更やアニメーション)
イベントリスナーの登録(マウスやキーボードのイベント監視)
初期化処理(コンポーネントがマウントされた時に一度だけ実行したい処理)
WebSocketの接続・切断
これらのユースケースでは、コンポーネントのライフサイクルに基づいて特定のタイミングで処理を実行したり、必要に応じてクリーンアップ(後処理)を行うことが求められます。
一般的な記法
import { useEffect } from "react";
const Example = () => {
useEffect(() => {
// ここに副作用を伴う処理を書く
return () => {
// ここにクリーンアップ関数を書く
};
}, [依存配列]);
};
上記のコードでは、useEffect に渡した関数が副作用処理を担当します。また、戻り値としてクリーンアップ関数を返すことができます。このクリーンアップ関数は、コンポーネントがアンマウントされるタイミングや依存配列に指定された値が変わった際に実行されます。
実行タイミング
useEffect は以下のタイミングで実行されます。
初回レンダリング時
コンポーネントが最初に画面に描画された直後に発火します。
- 依存配列の値が変更された時
- 依存配列に指定された値が更新された場合、そのタイミングで再度副作用の処理が実行されます。
- 依存配列が空([])の場合は、初回レンダリング時に一度だけ実行され、それ以降は発火しません。
クリーンアップ関数
クリーンアップ関数は以下の状況で実行されます。
- コンポーネントがアンマウントされる時
- 依存配列の値が変更され、再レンダリングが行われる時
- これは特に、イベントリスナーの解除や、WebSocketの切断、タイマーのクリアなどに利用されます。
再レンダリングとは?
再レンダリングとは、以下の条件でコンポーネントが再度描画されることを指します。
- コンポーネント自身の props が変更された時
- コンポーネント自身の state が変更された時
- 親コンポーネントが再レンダリングされた時
Reactでは、状態やプロパティの変化に基づいて必要に応じてコンポーネントが再描画されますが、その際に useEffect が再実行されることがあります。
useEffectの発火タイミング
useEffect はコンポーネントが「レンダリング」された後に実行されます。つまり、DOMが生成された後に副作用処理が行われます。これにより、DOMを操作する処理がDOMの生成前に実行されるという問題を防ぐことができます。
例として、以下のようなDOMの操作を伴う関数があったとします。
useEffect(() => {
const element = document.getElementById('my-element');
element.style.color = 'red'; // DOMが存在しないと実行できない
}, []);
この場合、useEffect がDOMの生成後に実行されるため、document.getElementById を使って問題なくDOMを操作できます。もしこれがDOM生成前に実行されると、操作対象の要素が存在しないためエラーが発生します。
ユースケースの確認
useEffect の具体的なユースケースを再確認しておくと、実際に副作用を伴う処理を行う際に、正しくライフサイクルに合わせて処理を行えるようになります。たとえば、API呼び出しやイベントリスナーの登録、さらにその解除までを管理するための重要な機能として、Reactコンポーネント開発において頻繁に使われるフックです。
このように、useEffect はReactコンポーネントのライフサイクルに基づいて、副作用の管理を行う非常に便利なフックです。正しいタイミングで処理を行い、適切にクリーンアップを行うことで、パフォーマンスの最適化やメモリリークの防止につながります。
最後に
認識に間違えがあったり、追記したほうがいいことがあったらコメントなどで教えていただけると幸いです。