コース一覧
Reactで状態・フォーム・リストを扱う
key

Reactで状態・フォーム・リストを扱う

useState、イベントハンドラ、制御されたinput、フォーム送信とバリデーション、mapによるリスト表示、key、条件レンダリング、空状態を扱う全25レッスンのコースです。入力・絞り込み・ダークモードへ反応する作品ギャラリーを作り、ユーザー操作で変化するUIの基本を身につけます。

1
state(useState)
01. なぜstateが必要か15分
02. useState15分
03. ボタンで更新15分
04. 複数のstate15分
05. オブジェクトのstate15分
06. 配列のstate15分
07. 再レンダリングの仕組み10分
08. つくる - ダークモード切替20分
09. 第4章クイズ15分
2
イベントとフォーム
01. イベントハンドラ15分
02. イベントオブジェクト15分
03. 制御されたinput15分
04. 複数の入力15分
05. フォーム送信15分
06. バリデーション15分
07. つくる - 問い合わせフォーム20分
08. 第5章クイズ15分
3
リストと条件レンダリング
01. mapでリスト描画15分
02. key15分
03. 条件レンダリング(&&)15分
04. 出し分け(三項)15分
05. 空状態15分
06. 絞り込みUI15分
07. つくる - ギャラリーReact版20分
08. 第6章クイズ15分

key

key はどの行がどのデータかの印

前回の警告を消します

map でカードを並べたとき、コンソールに次のような警告が出ていました。

プレーンテキスト

Warning: Each child in a list should have a unique "key" prop.

直し方は簡単で、map が返す一番外側の要素に key を付けるだけです。

JavaScript (JSX)

{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 も出します。

ヒント

key は map が返す一番外側の要素に付けます。中の h2 に付けても警告は消えません

data- で始まる属性は、そのまま HTML の属性として出力されます

App.jsx
プレビュー

できているか

  • work-card が3枚並んでいる
  • 1枚目のカードの data-work-id が 1 になっている
  • 3枚目のカードの data-work-id が 3 になっている
  • 3枚目に「写真ギャラリー」が表示されている
エディタを読み込んでいます