Open4
react.dev の useMemo の メモ
Ref
全てはここに書いてある
useMemoって何なの?
- レンダー間で計算結果をキャッシュするためのフック
- めっちゃ重い処理がある場合に使う
- 基本的に使わなくても良い
- よく分からんけど使っておけという認識であれば使わないほうが良い
- アプリケーションの動作が重いなと感じるのであれば使うと良い
- ごっついインタラクション(図形のアニメーションとか)がある場合は使うと良いかもしれない。
コードサンプル
import { useMemo } from 'react';
function TodoList({ todos, tab }) {
// ここから
const visibleTodos = useMemo(
() => filterTodos(todos, tab),
[todos, tab]
);
// ここまで
// 以下略
}
引数
第一引数: calculateValue
前述のサンプルコードの下記部分が calculateValue
といって、キャッシュしたい値を計算する関数。
純関数[1]である必要がある。
Reactが初回描画時にこの関数を呼び出す。
2回目以降は、後述する第二引数の dependencies
が直前の描画から変化していなければ同じ値を返す。
() => filterTodos(todos, tab),
第二引数: dependencies
配列となっている下記部分が dependencies
といって、 calculateValue
のコード内で利用されているすべてのリアクティブ値[2]の配列を書く。
配列の長さは一定である必要がある。
[todos, tab]
返り値
初回描画時は依存配列(dependencies
)無しで calculateValue
を呼び出した結果が返り値となる。
2回目以降は依存配列が変化してなければ、以前の描画で保存された値を返す。
変化していたらもう一度 calculateValue
を呼び出して、結果を返す。
そもそもメモ化って何よ?
呼び出した関数の結果をオブジェクトに保存(メモ)しておき、次回以降その関数を呼び出すときは保存しておいた値を利用する(不要な再計算を防ぐ)みたいな、プログラムの高速化に使われる技法。
Ref
計算コストが高いかどうかを調べる
対象の関数を console.time
と console.timeEnd
で挟んで、実行にかかった時間を計測する。
console.time('filter array');
const visibleTodos = filterTodos(todos, tab);
console.timeEnd('filter array');
上記のような計測方法の結果が 1ms
以上になった場合、メモ化の効果が期待できる。
その他補足
- useMemo は初回描画時は高速化しない。
- 一度実行したものをメモ化しておくわけだから当然っちゃあ当然
- 正確にパフォーマンスを計測するにはアプリを本番環境用にビルドする必要がある。できればユーザが持っているようなデバイスで動作検証するのが望ましい。