React が「なぜ再レンダリングするのか?」実際に動かして確認していった記録
React を触り始めた頃、「なぜここで再レンダリングが起きるのだろう?」と戸惑う場面がいくつかありました。
ドキュメントには「state が更新されると再レンダリングされます」と書かれているものの、実際に書いて動かしてみると、
「値は変わっていないはずなのに再レンダリングされている?」という状況が起き、仕組みを正しく理解できていないことに気づきました。
そこで、気になった挙動をひとつずつ調べたり、手元で試しながら整理した内容をまとめています。
■ 1. setState を呼ぶと、値が同じでも再レンダリングされる
まず最初に違和感を覚えたのがこれでした。
setCount(0);
count がすでに 0 でも、このコードを実行するとコンポーネントは再レンダリングされます。
なぜなのか気になって調べてみると、React は「値が変わったか」を見ているのではなく、
「state の更新が依頼されたかどうか」 を基準に判断しているということが分かりました。
つまり、値が同じでも「更新が行われた」という事実だけで再レンダリングが発生します。
■ 2. 配列やオブジェクトが“同じ内容でも毎回別物扱い”される理由
次に気になったのが、こちらの挙動です。
setUser({ name: "Taro" });
「中身は同じなのに、なぜ再レンダリングされるのか?」という疑問がありました。
実際に比較して確認してみると、次の結果になります。
{} === {} // false
オブジェクトは “参照型” のため、見た目が同じでも毎回新しく作られ、メモリ上では別々の参照になります。
React もこの「参照の違い」を根拠に更新を判断するため、同じ内容を渡しても「更新された」と解釈します。
【Tips】なぜ {} === {} は false になるのか?
- オブジェクトは“実体”ではなく「参照」で比較される
{}を書くたびに新しいオブジェクトが生成される- そのため
{} === {}は一致しない(false)
React はオブジェクトの中身までは比較せず、参照が変わったかどうか を基準にするため、再レンダリングの理由になります。
■ 3. useRef の値は変わっても再レンダリングされない
state と useRef の違いも実際に試してみると理解が進みました。
const countRef = useRef(0);
function increment() {
countRef.current++;
console.log(countRef.current);
}
このコードでは値は増えますが、画面の表示はまったく変わりません。
「useRef は値が変わっても再レンダリングを引き起こさない」というのを実際に確認した瞬間です。
ここで、画面に出さない値は state にしなくてよい という考え方が自然と腑に落ちました。
■ 4. 関数が毎レンダーで生成されることが子コンポーネント再レンダリングの原因だった
子コンポーネントが意図せず再レンダリングされる理由が分からず、props に渡している関数にログを仕込んで調べてみました。
<Child onClick={() => doSomething()} />
調べてみると、無名関数はレンダーのたびに新しい関数として生成されるため、
React は「props が変わった」と解釈し、子コンポーネントを再レンダリングしていました。
この挙動を理解したことで、useCallback を使う意味が明確になりました。
■ 5. setState の直後に値を読むと“古い値”になる理由
次に、setState の直後に console.log を置いてみたところ、意図した値が出ないことに気づきました。
setCount(count + 1);
console.log(count); // 更新されていない
調べてみると、React の state 更新は同期的ではなく、次のレンダリングで反映される という仕組みのためでした。
そこで、関数型アップデートを使うと常に最新の値を扱えることが分かりました。
setCount(prev => prev + 1);
■ 6. 親が再レンダリングすると子も再レンダリングされる
props が変わっていないのに子コンポーネントがレンダリングされる場面があり、気になって調べてみると、React は基本的に、
親が再レンダリングされると子も再レンダリングされる という仕様で動いていることが分かりました。
ここを理解してから、必要な場合に React.memo を使う意味がよりはっきりしました。
■ まとめ:実際に動かしていくと理解が進む
React の再レンダリングは仕組みだけ見ると複雑そうに見えますが、実際にログを出したり小さなコードを書いて確かめていくと、動き方が自然に掴めてきました。
- setState が呼ばれると値が同じでも再レンダリング
- 参照型(オブジェクト / 配列)は毎回別物として扱われる
- 表示に関係ない値は useRef に置くほうが適切
- 関数は毎回生成されるため props 経由で再レンダリングが増える
- state は「次のレンダー」で反映される仕組み
こうした挙動をひとつずつ確認していくことで、React の再レンダリングの仕組みがより理解しやすくなりました。

コメント