💡

React の useEffect について学んだことを整理する

2024/06/23に公開

useEffecttとは

useEffectは、Reactのフックの一つで、関数コンポーネントにおいて副作用を扱うために使用するhook。副作用とは、コンポーネントのレンダリングに直接関係しないが、実行する必要がある処理のことを指す。例えば、データのフェッチ、DOMの操作、など。

関数の実行タイミングをReactのレンダリング後まで遅らせるhookといえます。

記述方法

useEffect(() => {
  // 実行したい処理
}, [依存配列])

第二引数の依存配列によって次のように動作に差が出ます。

  • [ ](空配列)
    • ぺージを開いた時(初回レンダリング)だけ処理を行う
  • [ 特定の state 名]
    • 特定のstateが変わった時だけ処理を行う(再レンダリング)
  • 何も記載しない
    • コンポーネントがレンダリングされるたびに副作用関数が実行される。
    • 無限ループの温床になるため実際には、第2引数を省略するケースはほとんどないそうです。

使った場合の挙動

useEffectを使用すると、副作用関数が以下のタイミングで実行されます

  • コンポーネントのマウント時:
    • コンポーネントが初めてレンダリングされた後に実行される。
  • 依存配列が変更された時:
    • useEffectの第2引数に渡された依存配列の中の値が変更されたときに再実行される。依存配列を空にすると、マウント時のみ実行される。
  • コンポーネントのアンマウント時:
    • コンポーネントがDOMから削除されるときやタイマーのキャンセル(addEventLitenerの削除などアンマウント時)にクリーンアップ関数が実行される。

クリーンアップ関数とは何か

クリーンアップ関数は、副作用関数が返す関数として定義される。これは、コンポーネントがアンマウントされる際に、または副作用が再実行される前に呼び出される。

なぜクリーンアップ関数が必要か

クリーンアップ関数は、メモリリークを防ぐために重要。メモリリークとは、プログラムが不要になったメモリを解放しない現象で、システムのメモリが徐々に減少し、パフォーマンスが低下する原因となる。具体的には次のような場合に使用される:

  • イベントリスナーの削除:
    • イベントリスナーを追加したままにすると、コンポーネントがアンマウントされた後もリスナーが残り続け、メモリリークの原因となる。
useEffect(() => {
  const handleResize = () => {
    console.log('Window resized!');
  };
  window.addEventListener('resize', handleResize);

  // クリーンナップ関数でコンポーネントがアンマウントされたときにリスナーが削除され、メモリリークを防ぐ
  return () => {
    window.removeEventListener('resize', handleResize);
  };
}, []);
  • タイマーの解除:
    • タイマーを設定したままにすると、コンポーネントがアンマウントされた後もタイマーが動き続け、メモリリークの原因となる。
useEffect(() => {
  const timerId = setTimeout(() => {
    console.log('Hello, world!');
  }, 1000);

  // クリーンナップ関数でコンポーネントがアンマウントされたときにタイマーが解除され、メモリリークを防ぐ
  return () => {
    clearTimeout(timerId);
  };
}, []);

まとめ

  • useEffectとは、関数コンポーネントで副作用を扱うためのフックで、データのフェッチ、DOM操作、サブスクリプション、タイマー設定、イベントリスナー設定などで使う。
  • useEffectを使うことで、コンポーネントのマウント時、依存配列の変更時、アンマウント時に副作用関数が実行される。
  • クリーンアップ関数は副作用関数が返す関数で、コンポーネントのアンマウント時や再実行前に呼び出され、副作用を解除してメモリリークを防ぐ。

Discussion