0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

keyの仕組み

Posted at

Reactの描画のしくみ

Reactは、コンポーネントの表示を更新するときにこうします:

  1. 前回の仮想DOM(画面の状態)と、
  2. 今回の仮想DOM(更新後の状態)を
  3. 比較して「どこを変えればいいか」を判断

そのとき、リストのように同じ構造が何個も並んでいる部分では、

「この

は、前回のどのと同じものなの?」

が分からないと、正しい比較ができません


そこで使われるのが 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(順番が変わるとバグる)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?