以前にはじめてのReactアプリ作成の記事を作成しました。
上記のアプリを作成した際に発生したエラーについて、私が調べた範囲の内容をまとめてみようと思います。
発生したエラーと発生時の状況
Reactでのミニアプリを作成中に検証ツールのコンソールを見ていたところ、以下のようなエラーが発生しました。
// 視認性を上げるために文ごとに改行を加えています(原文は改行なし)
Encountered two children with the same key, `[object Object]`.
Keys should be unique so that components maintain their identity across updates.
Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.
発生時の該当箇所のコードは以下の通りでした。
// 配列の仮データ
const records = [
{ title: "勉強の記録1", time: 1 },
{ title: "勉強の記録2", time: 3 },
{ title: "勉強の記録3", time: 5 },
];
// 配列の各データを出力するJSX部分
{records.map((record) => {
return (
<div key={record}>
<p>{`${record.title} ${record.time}時間`}</p>
</div>
);
})}
</div>
エラーの原因考察
エラー文を和訳してみる
改めて今回のエラーを再確認してみましょう。
Encountered two children with the same key, `[object Object]`.
Keys should be unique so that components maintain their identity across updates.
Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.
この記述をDeepL翻訳にかけたところ以下のような結果が得られました。
同じキー
[object Object]
を持つ2つの子に遭遇しました。
キーは一意でなければなりません。そうすることで、コンポーネントは更新後も同一性を保つことができます。
一意でないキーは子要素の重複や省略を引き起こす可能性があります - この動作はサポートされておらず、将来のバージョンで変更される可能性があります。
ここから読み取れることとして、
- キーの値は要素を一意に示せるものでないといけない
- 重複する(ことが想定される)キー値を設定すべきではない
という点が考えられるでしょう。
つまり、map構文のkey値を設定する場合は要素が一意に定まる値を設定する必要があるということになります。
エラー部分のコードを再確認
改めて今回エラーが発生した部分のReactコードを見返してみます。
{records.map((record) => {
return (
<div key={record}>
<p>{`${record.title} ${record.time}時間`}</p>
</div>
);
})}
</div>
key
の値がrecords
のmap構文の引数であるrecord
となっていました。
これでは値が重複してしまう危険性があり、よくない記法でした。
改善案
結論としてはkey値には一意に定まるような値を設定しようということになります。
具体的には
- データのID値 (基本的にはデータに対して固有の値となるため)
- データのindex値 ※要素の順番が変わらない保証がある場合
あたりを設定すると良いと思います。
参考文献