はじめに
Reactを触っていて、なんとなくで様々なhooksを使っていましたが、一度自分の中での整理も含めて記事を書いてみようと思いました。
文章をパブリックに公開することは初めてなので、拙い箇所もあるとは思いますが、お暇なときにでも一瞥していただけると幸いに思います。
また記事内で間違えた記述や誤植があればご指摘いただけると嬉しく思います。
useMemoとは
React公式ドキュメントによると
「 useMemo is a React Hook that lets you cache the result of a calculation between re-renders. 」
と記述されています。
意訳すると「再レンダリングの間、計算結果をキャッシュとして保存しておくために用いる。」とのことです。
例
仮に
同じチームに所属する3人へそれぞれ「36を3乗せよ」という課題を与えたとします。(課題が与えられるタイミングはバラバラ)
この問題が1分で計算できるとしたら3人で3分の時間を費やすことになります。
しかしここで1人が1分かけて問題を解き、みんなが見える場所に「36×36×36=46656」と書いたメモを残したとします。
そうしたらどうでしょう。3人で3分かけていたところを3人で1分になりました。
チームとして2分の削減となりチームのパフォーマンスが向上しました。
上記のメモをRaectのレンダリングごとにで行ってくれるのがuseMemoの機能になります。
再レンダリング
もし「36の3乗」が「20の2乗」に変化したらメモは意味のないものになりますので、新たに「20×20=400」というメモを貼り出します。
これが値が変更され再レンダリングされた際の動作になります。
このように計算結果をメモしておくことでパフォーマンスの向上を狙うことが主な使用用途になると思います。
サンプル
const cachedValue = useMemo(calculateValue, dependencies)
第一引数には実行したい処理、第二引数には依存させたい値を入れておきます。
先ほどの例にあてはめますと第一引数には「363636=」の処理、第二引数には「20と乗算する値(2)」になります。
以下、useMemoのサンプルになります。
import React, { useMemo, useState } from 'react';
export const Calculate = () => {
const [number, setNumber] = useState(36);
const [power, setPower] = useState(3);
const [calcCount, setCalcCount] = useState(0); // 計算関数の実行回数
const [toggle, setToggle] = useState(true); // 再レンダリングをトリガーするための状態
// メモ化された計算関数
const result = useMemo(() => {
console.log('Calculating...');
setCalcCount(prev => prev + 1); // 計算関数の実行回数をインクリメント
return Math.pow(number, power);
}, [number, power]);
console.log('レンダリングされました。')
return (
<div>
<h1>課題</h1>
<div>
<label>
Number:
<input
type="number"
value={number}
onChange={(e) => setNumber(Number(e.target.value))}
/>
</label>
</div>
<div>
<label>
Power:
<input
type="number"
value={power}
onChange={(e) => setPower(Number(e.target.value))}
/>
</label>
</div>
<button onClick={() => setToggle(prev => !prev)}>
レンダリング
</button>
<div>
<p>結果: {result}</p>
<p>計算関数実行回数: {calcCount}</p>
</div>
</div>
);
}
お手元の環境にてコンソールの確認しながら、useMemoの第二引数の値を変更せずレンダリングボタンを押していただければ、コンソールにuseMemo内部の処理が行われていないことが確認いただけると思います。
※strict modeでは一部関数が2度行われるため、コンソールに2回表示されたりしますが気にしないでください。
参考文献
- [useMemo-React] https://react.dev/reference/react/useMemo