はじめに
テストコード作成時、表題のエラーが発生しました。動画で学んだなと思いつつ、忘れていたため記事にします。
問題
テストコード作成時、テーブル最後の行を取得するように試みたところ、「Each child in a list should have a unique "key" prop.」のエラーが発生
解決方法
mapでループして一行ずつレンダリングしている trタグに一意となるkeyを設定する。
※参考動画、ドキュメントより引用
reactの裏側で動いている仮想DOMの仕組みは、変更前と変更後の差分のみを抽出している。
ループでレンダリングした際に何個目の要素なのかを正確に比較するため、一意となる値の目印をつけてあげる必要がある。
indexの使用も可だが、非推奨
アイテムが挿入されたり削除されたり、配列の順序が入れ替わったり、アイテムのレンダリング順序は時間の経過とともに変化します。インデックスをキーに指定すると、微妙なバグや混乱を招くことがよくあります。
App.jsx
return (
<>
ー省略ー
<div>
<table>
<thead></thead>
<tbody>
{records.map((record) =>
- <tr>
+ <tr key={record.id}>
<td>
{`${record.title} ${record.time}時間`}
</td>
<td>
<button onClick={() => onClickDelete(record.id)}>削除</button>
</td>
</tr>
)}
</tbody>
</table>
<button data-testid="add" onClick={onClickAdd}>登録</button>
{error}<br />
合計時間:{totalTime} / 1000(h)
</div>
}
</>
)
}
export default App
おわりに
エラーに出会うことで、改めて基本事項をおさらいできるのはありがたいです。
参考