👻

keyにインデックスを使うのはやめよう

2024/08/11に公開

はじめに

この記事のVue版です。
Vueでも key にインデックスを使うのは良くないということを、上記の記事と同様のデモを作成して説明します。

対象読者

  • Vueの初学者の方
  • フロントエンド専門ではないが、Vueも書いているエンジニアの方

keyとは

公式ドキュメントの説明は以下の通りです。

特別な属性 key は、主に Vue の仮想 DOM アルゴリズムが新しいノードリストを古いリストに対して差分する際に、vnode を識別するためのヒントとして使用されます。
https://ja.vuejs.org/api/built-in-special-attributes#key

key は、Vue.jsでリストをレンダリングする際に各アイテムを一意に識別するために使用される重要な属性です。

key を適切に設定することで、Vueはアイテムの追跡を効率的に行い、リストの並び替えや要素の追加・削除時に正確にDOMを更新します。

公式ドキュメントでも推奨されているように、key には配列のインデックスではなく、各アイテムを一意に識別できる値を使用することが重要です。

これにより、意図しない不具合やパフォーマンスの低下を防ぐことができます。

keyにインデックスを使用すると

では、key にインデックスを指定するとどうなるのでしょうか。
単純にリストの表示だけであればおかしな挙動はしませんが、リストの要素を追加・削除・並び替えなどが発生すると、想定外の挙動が起こります。

こちらのデモをご覧ください。

左のリストは key にユニークなIDを指定し、右のリストはインデックスを指定しています。

ユニークなIDである4桁の数値をその行のテキストインプットに入力してからその行を削除すると、
左は行ごと削除されているのがわかると思いますが、右はテキストインプットの内容が残ったままになります。

また、リストの先頭に要素を追加しても、テキストインプットの内容は常に一番上に固定されたままです。

配列のインデックスが0の要素を削除しても、配列のインデックスが1から始まるわけではなく、あくまでインデックスは0スタートで変わりません。つまり、インデックスが1だった要素がインデックス0になるという動きになります。

そのため、key をインデックスにしていると、インデックス0の要素が配列から消えないのと同様に、テキストインプットの内容も消えません。

追加の場合も同様で、先頭に要素を追加すると、追加された要素のインデックスが0になるため、テキストインプットの内容はインデックス0のままで変更がありません。

おわりに

デモを作成することで、key にインデックスを指定することのリスクを実感できました。
皆さんも、key の指定には十分注意しましょう。

デモアプリのソースコードはこちらで公開しています。
https://github.com/hakushun/dm_vue-key

Discussion