Part 7 · レンダリングの仕組み
何が再レンダリングを起こすか
props が変わったから、ではない
再レンダリングが起きる理由は 2 つだけです。 自分の state が変わったときと、親がもう一度描き直されたときです。
ここで大切なのは、props が変わったからではないということです。 親が再レンダリングされると、子も再レンダリングされます。
子が props を受け取っていなくても再レンダリングされる
下のデモでは、子コンポーネントに props を渡していません。 それでも親のボタンを押すと、子の render 回数が増えます。
親の更新で子も再レンダリング
親の state を更新すると、子も再び実行される
親のカウント: 0
子コンポーネント
この子は props を受け取っていません。
React は子の関数をもう一度実行して、その結果を比べます。 props が同じでも、親が再び描き直されるときは子も動きます。
parent-re-renders-child.tsx
"use client";
import { useTrackDemoRender } from "@/components/lesson/demo-card";
import { Button } from "@/components/ui/button";
import { useState } from "react";
function Child() {
useTrackDemoRender();
return (
<div className="rounded-xl border border-slate-200 bg-slate-50 p-4 text-sm">
<p className="font-semibold">子コンポーネント</p>
<p>この子は props を受け取っていません。</p>
</div>
);
}
export function ParentRerendersChild() {
const [count, setCount] = useState(0);
return (
<div className="flex flex-col gap-4">
<div className="rounded-xl border border-slate-200 bg-slate-50 p-4">
<p>親のカウント: {count}</p>
<Button size="sm" onClick={() => setCount((current) => current + 1)}>
親を更新する
</Button>
</div>
<Child />
</div>
);
}props の変化はきっかけではない
function Child() {
useTrackDemoRender();
return <p>私は props を受け取っていません。</p>;
}
function Parent() {
const [count, setCount] = useState(0);
return (
<div>
<button onClick={() => setCount((current) => current + 1)}>
親を更新する
</button>
<Child />
</div>
);
}この例では、子が受け取る値はありません。 それでも親が更新されれば、子の関数は再び呼ばれます。
parent-re-renders-child.tsx
"use client";
import { useTrackDemoRender } from "@/components/lesson/demo-card";
import { Button } from "@/components/ui/button";
import { useState } from "react";
function Child() {
useTrackDemoRender();
return (
<div className="rounded-xl border border-slate-200 bg-slate-50 p-4 text-sm">
<p className="font-semibold">子コンポーネント</p>
<p>この子は props を受け取っていません。</p>
</div>
);
}
export function ParentRerendersChild() {
const [count, setCount] = useState(0);
return (
<div className="flex flex-col gap-4">
<div className="rounded-xl border border-slate-200 bg-slate-50 p-4">
<p>親のカウント: {count}</p>
<Button size="sm" onClick={() => setCount((current) => current + 1)}>
親を更新する
</Button>
</div>
<Child />
</div>
);
}理解できたか確かめる
確認クイズ
子コンポーネントの props が同じでも再レンダリングされるのはどちらの場合?
確認クイズ
親が再レンダリングするとき、子はどうなりますか?
parent-re-renders-child.tsx
"use client";
import { useTrackDemoRender } from "@/components/lesson/demo-card";
import { Button } from "@/components/ui/button";
import { useState } from "react";
function Child() {
useTrackDemoRender();
return (
<div className="rounded-xl border border-slate-200 bg-slate-50 p-4 text-sm">
<p className="font-semibold">子コンポーネント</p>
<p>この子は props を受け取っていません。</p>
</div>
);
}
export function ParentRerendersChild() {
const [count, setCount] = useState(0);
return (
<div className="flex flex-col gap-4">
<div className="rounded-xl border border-slate-200 bg-slate-50 p-4">
<p>親のカウント: {count}</p>
<Button size="sm" onClick={() => setCount((current) => current + 1)}>
親を更新する
</Button>
</div>
<Child />
</div>
);
}