key
前回の警告を消します
map でカードを並べたとき、コンソールに次のような警告が出ていました。
Warning: Each child in a list should have a unique "key" prop.直し方は簡単で、map が返す一番外側の要素に key を付けるだけです。
{works.map((work) => (
<div className="work-card" key={work.id}>
<h2>{work.title}</h2>
</div>
))}大事なのは、なぜ React がこれを求めるのかのほうです。
key は「どの行がどのデータか」の印
React は state が変わるたびに、前の画面と新しい画面を見比べて、違うところだけを書きかえます。このとき一覧の中身が並べ替わったり1件消えたりすると、React は「2番目の要素が別のデータに変わった」のか「1番目が消えて全体が1つ上がった」のかを、見た目だけからは区別できません。
key はその区別のために付ける印です。key があると、React は同じ key の要素を同じものとして追いかけ、消えた1件ぶんだけを取り除きます。key が無いと並び順で機械的に比べるので、入力中の文字やチェックの状態が別の行にずれて残る、という分かりにくいバグが起きます。
何を key にするか
一覧の中で重複しない値を使います。今回の作品データなら work.id が最適です。key は兄弟の中だけで一意ならよく、ページ全体で唯一である必要はありません。
配列の添字を key={index} とするのは最後の手段です。並べ替えも削除もしない一覧なら動きますが、先頭に1件足しただけで全部の添字がずれて、key が印の役目を果たさなくなります。タイトルのように後から変わる値や、Math.random() のように描くたびに変わる値も使ってはいけません。毎回すべてが「別のもの」になり、React が全部作り直します。
key は画面には出ません
key は React が内部で使う印なので、HTML の属性としては出力されません。ブラウザの検証ツールで見ても key は見当たりません。もし id を画面側でも使いたいなら、data-work-id のような data- 属性を別に付けます。こちらは普通の属性として出力されます。
演習
一覧に key を付けて警告を消し、あわせて確認用の data-work-id も出します。