Reactの描画のしくみ
Reactは、コンポーネントの表示を更新するときにこうします:
- 前回の仮想DOM(画面の状態)と、
- 今回の仮想DOM(更新後の状態)を
- 比較して「どこを変えればいいか」を判断
そのとき、リストのように同じ構造が何個も並んでいる部分では、
「この
は、前回のどのと同じものなの?」
が分からないと、正しい比較ができません。
そこで使われるのが key
Reactは、key
を使って「この要素はこれだよ!**」と判別します。
つまり:
-
key
が同じ → 同じ要素と見なす -
key
が違う → 新しい要素と見なして入れ替える
key
がない or indexを使うと起きるバグの例
例:フォームがリストにあるとき
const items = ['A', 'B', 'C'];
const [list, setList] = useStat(items);
return (
<ul>
{list.map((item, index) => (
<li key={index}>
{item}
<input />
</li>
))}
</ul>
);
- それぞれの項目に
<input>
を入れている - しかし、
index
を key に使っていると…
要素の順番を変更 or 削除したとき:
- 入力していたテキストが別の項目に移動してしまう
- なぜかというと、Reactが間違った要素を同じ認識するから
key
には「一意で変わらないID」を使うべき
const tasks = [
{ id: 't1', text: '掃除' },
{ id: 't2', text: '洗濯' }
];
return (
<ul>
{tasks.map(task => (
<li key={task.id}>{task.text}</li>
))}
</ul>
);
このように、**ユニークで安定したID(例:DBのID)**を使うと完璧です。
要素を追加・削除・並び替えしたときの比較例
keyがない(またはindex)
Before: <li key=0>🍎</li> <li key=1>🍌</li>
After: <li key=0>🍌</li> <li key=1>🍇</li>
React「え?index 0は🍎のまま?じゃあ🍌の中身に🍎を使い回そう」
→ UIがズレる💦
keyがある
Before: <li key="apple">🍎</li> <li key="banana">🍌</li>
After: <li key="banana">🍌</li> <li key="grape">🍇</li>
React「keyが違うね。bananaは残すけど、apple→grapeに変えよう」
→ UIが正しく更新✨
まとめ:keyとは?
ポイント | 説明 |
---|---|
目的 | 要素の識別と効率的な再描画のため |
理由 | 仮想DOMで差分を比べるために必要 |
良い例 | ユーザーID、タスクIDなど一意なID |
悪い例 |
index (順番が変わるとバグる) |