【ReactHooks】useEffectまとめ
目次
useEffectとは?
useEffectとは、関数の実行タイミングをReactのレンダリング後まで遅らせるフックです。
公式ドキュメントには、関数のことを副作用と呼んでおり、DOMの更新の後に副作用を呼び出すと書いてあります。
副作用とは、「DOMの書き換え操作」「サーバー通信(WebAPI通信)」「変数の書き換え」「ログの記録」などUI構築以外の処理を指します。
DOMの書き換え操作に関しては、レンダリング後じゃないとDOM上に要素が存在しないため、useEffectを使うことによって確実にDOMの書き換えが行えます。
時間のかかるWebAPI通信に関してもuseEffectでレンダリング後に行うことができます。
関数コンポーネントには基本レンダリングに関する処理しか書かないので、API通信のようなレンダリングと関係ない処理はuseEffectの中に書くことになります。
このようにuseEffectはレンダリングに関係ない処理を関数コンポーネント外に追いやるという側面も持っています。
useEffectの使い方
useEffectを使うために、まずuseEffectをインポートします。
import { useEffect } from 'react';
useEffectの基本的な書き方は以下の通りです。これもuseStateなどと同様に関数コンポーネントのトップレベルで宣言します。
useEffect(
() => { fetchAPIFunction() }, // 第1引数は実行させたい副作用関数を設定!
[依存する変数の配列など] ) // 第2引数は複数のパターンがある!
第1引数には先ほど説明したAPI通信などの副作用関数を設定します。
第2引数には複数のパターンがあり、設定の仕方によって副作用関数の実行タイミングを制御することができます。
第2引数について
第2引数に何も設定しない場合
useEffect(
() => { fetchAPIFunction() },
)
この場合はコンポーネントのレンダリング後にとにかく毎回、副作用関数が実行されます。
このパターンは実際にはあまり使うことは少ないです。ログを出力させる時などに使うことがあります。
第2引数に空の配列を設定する場合
useEffect(
() => { fetchAPIFunction() },
[] )
この場合はコンポーネントの1番最初のレンダリング後にのみ副作用関数が実行されます。
第2引数に変数を入れた配列を設定する場合
useEffect(
() => { fetchAPIFunction() },
[count, isFlugChanged] ) // 第2引数に変数を入れた配列を設定するパターン
この場合は、1番最初のレンダリング後と第2引数の配列に入れた変数のいずれかの値が変更された時に副作用関数が実行されます。
配列には変数を1つだけ入れてもいいし、複数入れることもできます。
上記の例の場合だと、1番最初のレンダリング後、countの値が変更されたとき、isFlugChangedの値が変更されたときに実行されることになります。
このように第2引数に具体的な変数を設定することで、副作用関数の実行タイミングを制御することができます。
これにより不要なレンダリングを減らすことができ、サイトのパフォーマンスを向上させることができます✨
useEffectで無駄なレンダリングを減らすじょ!
クリーンアップについて
副作用は2種類に分類することができ、クリーンアップを必要としない副作用と、必要とする副作用があります。
クリーンアップを必要としない副作用は「DOMの書き換え操作」「サーバー通信(WebAPI通信)」「変数の書き換え」「ログの記録」などが該当しますが、
「イベントリスナーの追加」「タイマーの設定」などはクリーンナップを必要とする副作用に該当します。
「DOMの書き換え操作」「サーバー通信(WebAPI通信)」「変数の書き換え」「ログの記録」については処理を実行した後、その処理が持続して実行されず、一度で終わるためであり、
「イベントリスナーの追加」「タイマーの設定」はその処理をキャンセルしないと処理が続いてしまうため、キャンセルするクリーンアップが必要になるということです。
よってクリーンアップとは「イベントリスナーの削除」や「タイマーのキャンセル」をして前回の副作用を削除することを指します。
クリーンアップするときは第1引数の副作用関数を書いた後に、returnで「イベントリスナーの削除」や「タイマーのキャンセル」する関数を返します。
useEffect(() => {
// 副作用関数
element.addEventListener('click', () => {
// イベント処理
event();
})
// returnでクリーンアップする!!
return () => {
element.removeEventListener('click', () => { event(); })
}
}, [])
関連記事