こんにちは!Reactの世界へようこそ。
日々コードを書いていると、「画面を更新するたびに、裏側でとんでもない量の再計算が行われているのでは…?」と不安になる夜、ありますよね。
今日は、Reactのパフォーマンス最適化における「三種の神器」、`React.memo`、`useMemo`、`useCallback`についてお話しします。これらを使うと、Reactという名の「超優秀だけど少しおせっかいな執事」に、適切な指示を出せるようになります。
さあ、肩の力を抜いて、一緒に見ていきましょう。
—
1. Reactという「おせっかいな執事」の正体
Reactは、データが少しでも変わると、関連するコンポーネントを「はい、やり直し!」といって全部再レンダリングする癖があります。これは画面の整合性を保つための「誠実さ」なのですが、正直なところ、「いや、そこは変わってないから再計算しなくていいよ!」という場面も多いんです。
この「無駄な再計算」を防ぐための魔法が、今回の3つです。
—
2. React.memo:コンポーネントを「冷凍保存」する
`React.memo`は、コンポーネント全体を包み込むことで、「渡ってくるデータ(Props)が変わらなければ、中身を再描画しない」という指示を出す仕組みです。
例えるなら、「いつものオーダー」なら調理せずに冷蔵庫から出すようなイメージです。
import React from ‘react’;
// 普通のコンポーネントだと、親が変わるたびに再レンダリングされますが…
// React.memoで囲むと「Propsが変わらない限り、前の結果を使い回す」ようになります。
const UserProfile = React.memo(({ name }) => {
console.log(“プロフィールを描画中…”); // Propsが変わらないなら、このログは出ません!
return
;
});
ここでの注意点: 闇雲に全部囲むのはやめましょう。比較作業自体にコストがかかるので、複雑な計算をするコンポーネントだけに使うのが「プロの加減」です。
—
3. useMemo:計算結果を「メモ帳に控える」
`useMemo`は、「重い計算結果」をメモ帳に書き留めておくための道具です。
例えば、1万件のデータから特定の条件に合うものを探すような処理。毎回これを計算していたらブラウザが悲鳴を上げますよね。`useMemo`を使えば、「データが同じなら、計算せずにメモ帳の答えをそのまま渡す」ことができます。
import { useMemo } from ‘react’;
function Dashboard({ items }) {
// itemsの中身が変わらない限り、この重い計算はスキップされます
const expensiveResult = useMemo(() => {
console.log(“重い計算を実行中…”);
return items.filter(item => item.isImportant).length;
}, [items]); // itemsに変化があった時だけ再計算する
return
;
}
—
4. useCallback:関数そのものを「指名手配」する
これが一番つまずきやすいポイントです!
Reactでは、コンポーネントが再レンダリングされるたびに、中にある関数は「新しく作り直された別の関数」とみなされます。
たとえ中身が同じでも、「メモリ上の住所が違う」ので、Reactは「別物だ!」と判断して再レンダリングを引き起こしてしまうのです。`useCallback`は、その「関数の住所」を固定してあげるための道具です。
import { useCallback } from ‘react’;
function Parent() {
// useCallbackを使わないと、Parentが更新されるたびに
// このhandleClickは「新しい関数」として作られてしまい、
// 子コンポーネントが「あれ?新しい関数が来た!」と勘違いして再描画されます。
const handleClick = useCallback(() => {
console.log(“ボタンが押されました”);
}, []); // 依存配列が空なら、この関数は一生同じ住所を指し続けます
return ;
}
—
5. 最適化の「境界線」を見極める極意
最後に、伝説的なチーフアーキテクトからのアドバイスを一つ。
「最初から最適化しないでください」
コードが複雑になる前にこれらを導入するのは、まだ走れない赤ちゃんに高級なランニングシューズを履かせるようなものです。まずは普通に動くものを作り、「あれ、このリストの操作、ちょっとカクつくな?」と感じてから、初めてツールボックスを開いてください。
- React.memo: 子コンポーネントが頻繁にレンダリングされる時に。
- useMemo: 明らかに「重い」計算がある時に。
- useCallback: `React.memo`を使っている子コンポーネントに、関数を渡す時に。
この3つを適切に使い分ければ、あなたのReactアプリは驚くほど軽快で、美しい挙動を見せてくれるはずです。
最初は難しく感じるかもしれませんが、大丈夫。一つずつ試していけば、必ず「あ、今のタイミングでメモ化すればいいんだな」という勘所が掴めるようになりますよ。応援しています!

コメント