こんにちは。Reactの世界へようこそ。
日々コードを書いていると、「あれ? ちょっと画面の動きが重いな」とか「意図しないところで何度も再計算が走っている気がする」なんて悩みにぶつかることはありませんか?
特にReactの「Context API」は便利すぎて、一度使い始めると魔法のように感じますよね。でも、その魔法にはちょっとした「落とし穴」があるんです。今日は、Contextが引き起こす「無駄な再レンダリング」というちょっとした厄介者を、誰にでもわかるように紐解いていきましょう。
—
Contextという名の「巨大な掲示板」
まず、Contextをイメージしてみてください。
例えば、オフィスに「全員が見ている巨大なホワイトボード」があるとします。
誰かがそこに「今日はカレーの日です!」と書き込みをすると、ホワイトボードを見ている全員が、「お、カレーの日か!」と反応して振り向きますよね。
ReactのContextも同じです。`value`として渡したデータが一つでも変わると、そのContextを使っているすべてのコンポーネントが「更新があった!」と認識して、一斉に再レンダリング(再計算)を始めてしまうんです。
もし、そのホワイトボードに「今の時刻(1秒ごとに変化)」と「ユーザー名」が一緒に書かれていたらどうでしょう? ユーザー名が変わらなくても、時刻が変わるたびに全員が立ち上がって確認しに行くことになります。これはちょっと疲れますよね。
—
対策その1:データを「小分け」にする
一番シンプルな解決策は、大きなホワイトボードを「役割ごとに分ける」ことです。
「時刻用」のホワイトボードと「ユーザー情報用」のホワイトボードに分ければ、時刻が更新されても、ユーザー情報だけを見ている人は「あ、関係ないや」と座ったままでいられます。
// ユーザー情報専用のContext
const UserContext = createContext();
// 時刻専用のContext
const TimeContext = createContext();
function App() {
return (
{/ これでユーザーデータが変わっても、時刻コンポーネントは無反応! /}
);
}
—
対策その2:値を「メモ(覚え書き)」しておく
次に、Reactにおける「メモ化(memoization)」というテクニックです。
`useMemo`という魔法の道具を使います。これは、「渡す値が本当に変わったときだけ、新しく作り直す」というルールを決めるものです。
もし、親コンポーネントが再レンダリングされるたびに、新しいオブジェクトをContextに渡してしまうと、中身が同じでもReactは「あ、新しいものが来た!」と勘違いして再レンダリングを誘発してしまいます。
const value = useMemo(() => {
// ここで値を計算します。
// 依存配列([user])の中身が変わらない限り、前と同じ値を使い回します。
return { user, updateName };
}, [user]);
// こうすれば、親が何回レンダリングされても、
// valueの中身が同じなら、子コンポーネントは「変化なし」と判断して落ち着いていてくれます。
—
対策その3:コンポーネントを「細かく分ける」
これが現場で最も効く、最強の戦略です。
Contextを使っているコンポーネントが大きすぎると、影響範囲が広がりすぎてしまいます。
「データを受け取るだけの器」と「実際に画面を表示する中身」を分離するイメージです。
// 【悪い例】このコンポーネント全体が、Contextの更新で毎回再計算される
function Header() {
const { user } = useContext(UserContext);
return
;
}
// 【良い例】中身を小さく切り出す
function UserDisplay() {
const { user } = useContext(UserContext); // ここだけが再レンダリングされる
return
;
}
function Header() {
return (
);
}
—
最後に:完璧を目指さなくていいんです
ここまで読んで、「うわ、毎回こんなこと考えなきゃいけないの?」と不安になった方もいるかもしれません。でも、安心してください。
最初から完璧なパフォーマンスを追求して、コードを複雑にしすぎる必要はありません。「なんとなく動きがモタつくな?」と感じた時に、今日お話しした「分ける」「メモする」「切り出す」という引き出しを思い出せばいいんです。
Reactは、あなたの書いたコードが成長していくのを見守る、とても優しいツールです。焦らず、一歩ずつ、納得しながら進んでいきましょう。
また困ったことがあったら、いつでも相談してくださいね。応援しています!

コメント