React Hooks ∋ useEffect

コンポーネントのライフサイクル時に処理を行うために使います。ライフサイクルとはコンポーネントが、

  1. レンダリングされた時
  2. リレンダリング(更新)された時
  3. 削除される時

です。

useEffectは引数に2つの値を渡します。1つ目は上記のライフサイクル処理を行う関数、2つ目はライフサイクル時に関数を発火するかどうかの依存条件をuseCallbackらと同じように渡します。戻り値はありません。

以下は例です。

const [foo] = useState('');

useEffect(
  () => {
    console.log(foo);
  }, [foo]
);

useEffectはレンダリング後に1回は必ず呼ばれます。その後は引数の条件によって発火するかが変わります。このコードではfooが依存条件としてセットされているのでfoo更新された後にも発火されます。

ライフサイクルの1と2は出てきましたが3はどう使うのか。実は、上記のコードではこれは実装されていません。3を行うには1つ目の引数の関数を修正する必要があります。それは、関数の戻り値として関数を返す事です。

少し書き換えます。

const [foo] = useState('');

useEffect(
  () => {
    console.log(foo);
    
    return () => {
      console.log('unmount');
    }
  }, [foo]
);

これでこのコンポーネントが削除される際にunmountとコンソールに表示されるはずです。

2以外を実装

つまり更新時の処理はいらないを実現する方法です。これは依存条件に空配列を渡すだけで実装できます。
「最初の1回は必ず実行され…最後にも1回…」

useEffect(
  () => () => { /* ... */ }
  []
);

ここから3の削除時のライフサイクルもいらない場合はどうするか。関数を返さなければいいですね。

useEffect(
  () => { /* ... */ }
  []
);

useLayoutEffect

ちなみにこちらの似たフックは、レンダリングされて反映される直前に実行されるライフサイクルです。ライフサイクルの順番が早いのはuseLayoutEffect > useEffectです。