MeWrite Docs

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

Reactで配列をレンダリングする際にkey propが不足している警告

概要

Reactで配列をmap()などで展開してレンダリングする際、各要素にユニークなkeyプロパティを指定していない場合に発生する警告です。keyはReactが要素を識別し、効率的に再レンダリングするために必要です。

エラーメッセージ

Warning: Each child in a list should have a unique "key" prop.
Check the render method of `ComponentName`.

原因

  1. keyの指定忘れ: map()で生成した要素にkeyを付けていない
  2. 非ユニークなkey: 同じ値のkeyが複数存在する
  3. インデックスをkeyに使用: 配列の順序が変わる場合に問題
  4. ネストしたリスト: 内側のリストでkeyを忘れる

解決策

1. ユニークなIDをkeyに使用

1
2
3
4
5
6
7
8
9
// Bad
{items.map(item => (
  <li>{item.name}</li>
))}

// Good: IDをkeyに使用
{items.map(item => (
  <li key={item.id}>{item.name}</li>
))}

2. インデックスは最終手段

1
2
3
4
5
6
7
// 許容される場合(静的なリストで並び替えがない)
{staticItems.map((item, index) => (
  <li key={index}>{item}</li>
))}

// 非推奨(並び替えや追加削除がある場合)
// インデックスをkeyにすると、要素の状態が正しく維持されない

3. 複合キーの作成

1
2
3
4
5
6
// IDがない場合、複数のプロパティを組み合わせる
{items.map(item => (
  <li key={`${item.category}-${item.name}`}>
    {item.name}
  </li>
))}

4. ユニークIDの生成

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import { nanoid } from 'nanoid';

// 初期化時にIDを付与
const itemsWithIds = items.map(item => ({
  ...item,
  id: nanoid()
}));

// または crypto.randomUUID()
const itemsWithIds = items.map(item => ({
  ...item,
  id: crypto.randomUUID()
}));

5. Fragmentでのkey

1
2
3
4
5
6
7
8
9
// Fragmentにもkeyが必要な場合
{items.map(item => (
  <React.Fragment key={item.id}>
    <dt>{item.term}</dt>
    <dd>{item.definition}</dd>
  </React.Fragment>
))}

// 短縮構文<></>はkeyを受け取れない

6. ネストしたリスト

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{categories.map(category => (
  <div key={category.id}>
    <h2>{category.name}</h2>
    <ul>
      {category.items.map(item => (
        <li key={item.id}>{item.name}</li>  {/* 内側にもkey */}
      ))}
    </ul>
  </div>
))}

7. コンポーネントの抽出

1
2
3
4
5
6
7
8
9
// リストアイテムをコンポーネント化
function ListItem({ item }) {
  return <li>{item.name}</li>;
}

// 親コンポーネント
{items.map(item => (
  <ListItem key={item.id} item={item} />
))}

keyの重要性

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// keyがないと、Reactは要素を正しく追跡できない
// 例: input要素の状態が保持されない

// Bad: インデックスをkey
{items.map((item, index) => (
  <input key={index} defaultValue={item.name} />
))}
// items配列が並び替えられると、inputの内容がずれる

// Good: ユニークID
{items.map(item => (
  <input key={item.id} defaultValue={item.name} />
))}
// 並び替えても各inputは正しいitemに紐づく

よくある間違い

  • Math.random()をkeyに使用(毎回変わるため非効率)
  • 親コンポーネントではなく子コンポーネント内でkeyを設定
  • keyを子コンポーネントのpropsとして使おうとする(keyはpropsに含まれない)

関連エラー

参考リンク

React の他のエラー

最終更新: 2025-12-13