【React入門】絶対に理解させる(たい)useMemo【初学者向け】
まえがき
React Hooksの中の一つ、useMemoについて解説する。厳密で難しい話をするのではなく、理解させることを目的としている。
対象読者
- React勉強中の方
-
useStateはギリいけるぞって方
useMemoって何
- 重たい処理・計算結果の値を保持して、無駄な計算をしないようにするためのHooks
-
パフォーマンスを向上させる目的のHooksであるから、
useMemoがないと実装できないってことは基本的にない
処理のサンプルコード
まず重い処理をするコードを見てくれ
const culc = (x: number, y: number) => {
let i = 0;
while (i < 10000) {
console.log("重い処理だよ");
i++;
}
return x * y;
};
この関数は重たい処理をして、結果的に引数の二つの数値の積を返すぞ
useMemoを利用しない場合
次に、メモ化せずにこの関数の返り値を使うコードを見てくれ
const [x, setX] = useState<number>(10);
const [y, setY] = useState<number>(20);
const result = culc(x, y);
ごく普通の実装だ。この状態で、同じ画面にあるx,yの増減に全く関係ないボタン(Stateを変更する)を押してみる。

(自ブログの開発画面です)
x,yの値が全く変わっていないにもかかわらず、ボタンを押すたびに毎回関数が実行されてconsoleが表示されている。これは明らかに不要な実行である。
このように、useMemoを利用していないresultは、コンポーネントが再レンダリングされるたびに計算される。
再レンダリングって何
- 画面を更新(再描画)するために、JavaScriptをもう一回読み込み直すことだぞ
- 基本的に以下のタイミングで再レンダリングが走るぞ
- 自コンポーネントの
Propsが更新された時 - 自コンポーネントの
Stateが変更された時 ← 今回はボタンを押してStateが変更されたからこれ - 親コンポーネントが再レンダリングされた時
- 自コンポーネントの
useMemoを利用した場合
では、useMemoを利用して関数の返り値をメモ化(保持)するコードを見てくれ
const [x, setX] = useState<number>(10);
const [y, setY] = useState<number>(20);
const memoResult = useMemo(() => culc(x, y), [x, y]);
この状態で、同じ画面にあるx,yの増減に全く関係ないボタン(Stateを変更する)を押してみる。
すると、全くconsoleが表示されない。つまり、関数が実行されていないということになる。
本来、x * yを計算するというこの関数は、x,yのどちらも変更がない場合は、再レンダリングの際にいちいち再計算する必要がないので、これで不要な処理をスキップし、パフォーマンスを向上させることができた。
もちろんx,yが変更される場合(x,yを変化させるボタンの押下時など)はmemoResultの値は再計算される。
一般化した使い方の例
const memoResult = useMemo(() => {
// ここに処理を書く
}, [依存する変数をここに並べる(依存配列という)]);
- 依存する変数が変わらない限り、処理は実行されないぞ
- 処理が重たい時に効果を発揮するぞ(再計算が不必要な時にスキップされるため)
- 処理に使う変数を依存配列に入れるぞ(過不足なく入れることが重要)
依存配列に何を入れるべきか
const memoResult = useMemo(() => {
let i = 0;
while (i < 10000) {
console.log("メモされてる方");
i++;
}
return x * y;
}, [x, y]);
もしこのコードの依存配列が[x]のみだったら、もしyのみが変更された時、useMemoの処理が実行されないのでx * yが更新されない。これは間違った実装である。
逆に、依存配列が[x, y, z]であったら、zのみが変更された場合にもuseMemoの処理が実行される。しかし、計算結果はx * yであるから、計算結果の変化は全くない。つまり依存配列にzは必要なく、間違った実装である。
よって、関数に必要である変数を過不足なく依存配列に入れる必要がある。
まとめ
-
useMemoはReactのHooksで、計算結果をメモ化することでパフォーマンスを向上させる -
useMemoを使わない場合、コンポーネントが再レンダリングされるたびに計算が実行される -
useMemoを使用すると、指定した依存配列が変わらない限り、以前の計算結果を再利用する -
useMemoは、重い計算処理が頻繁に行われる場合や、同じ結果が再利用できる場合に使用すると効果的
このようにして、useMemoを使うことでReactコンポーネントのパフォーマンスを向上させることができるぞ🚗
追伸 ✍️
Next.jsを用いた個人ブログサイト『がむログ』でも記事を投稿しています。技術記事から趣味日記まで投稿しているので、興味がある方はぜひ見てみてください👀👀
Discussion