はじめに
React
の再レンダリングとメモ化、について学習したことを簡単にまとめてみました。
参考
わかりやすく有益な記事で、参考にさせていただきした。
本当にありがとうございました!!
- https://qiita.com/soarflat/items/b9d3d17b8ab1f5dbfed2#usecallback-%E3%82%92%E9%96%A2%E6%95%B0%E3%81%AE%E5%86%8D%E7%94%9F%E6%88%90%E3%82%92%E9%98%B2%E3%81%90%E7%9B%AE%E7%9A%84%E3%81%A7%E5%88%A9%E7%94%A8%E3%81%97%E3%81%A6%E3%81%AF%E3%81%84%E3%81%91%E3%81%AA%E3%81%84%E3%81%AE%E3%81%8B
- https://zenn.dev/b1essk/articles/react-re-rendering
コンポーネントの再レンダリングが起きる条件
1. state
が更新されたとき
例:フォーム入力の値を監視するstate
を保持しており、そのstate
の値に変更があったとき(フォームに値を入力 or 削除するとき)
2. props
が更新されたとき
例:親コンポーネントで値を保持しており、その値をprops
で子コンポーネントに渡して表示している際にその値に変更があったとき
3. 親コンポーネントが再レンダリングされるとき
メモ化による再レンダリングの最適化
再レンダリングの最適化とは
Reactのコンポーネントではレンダリングは頻繁に起きることが多いため、そのたびに重い処理などを走らせるとパフォーマンスが落ちる。
その不必要な処理をできるだけ抑え、処理は必要最低限にしたい。
それによりページ描画スピード向上など、パフォーマンスの最適化をはかることが再レンダリングの最適化である。
メモ化とは
計算処理結果や生成された関数、コンポーネントなどを保持しておき、それを適切に再利用すること。
メモ化しておくことで不必要に処理を走らせることを防ぐことができる。
※メモ化すること事態にもコストが発生するようなので、何でもかんでもメモ化すれば良いということでもないようである。
メモ化の方法
-
memo()
コンポーネントに対してのメモ化 -
useCallback()
コールバック関数に対してのメモ化 -
useMemo()
値に対してのメモ化
memo()
コンポーネントに対してのメモ化
親コンポーネントが再レンダリングされても、子コンポーネントに渡すprops
の値が変更されない限り、子コンポーネントは再レンダリングされないようにする仕組み。
逆に言えばmemo()
を利用してもprops
に変更があれば再レンダリングされてしまう。
memo(コンポーネント);
useCallback()
コールバック関数に対してのメモ化
不必要に関数が再生成されることを防ぐ。
第2引数で指定する依存配列
に変更がない限り第1引数のコールバック関数は再生成されず、メモ化された保持している関数をコールバック関数を返す。
useCallback
を利用しないと、このコンポーネントがレンダリングされるたびにその関数は再生成される。この関数をprops
として渡していたら、再生成のタイミングでprops
が変更されたことを子コンポーネントが検知して子コンポーネントも再レンダリングされる。
const 関数名 = useCallback(コールバック関数, [依存配列]);
※ 利用方針は様々あると思うが、基本的にはmemo(コンポーネント)
とセットで利用することで子コンポーネントの不必要な再レンダリングを防ぐ目的で利用する。
useMemo()
値に対してのメモ化
不必要に重い処理を走らせることを防ぐ。
第2引数で指定する依存配列
に変更がない限り第1引数の処理は実行されず、メモ化された保持している値を返す。
const 変数名 = useMemo(処理, [依存配列]);
※第1引数で渡す処理が重い処理でなければ、useMemo()
を利用するコストの方が大きくなることもあり、利用するメリットが無いこともあるよう。