Each child in a list should have a unique “key” prop.について

JavaScript

画面自体は問題なく表示されてるけど、なんかコンソールに警告が出力される。

key属性を設定していないのが原因で発生していた

Reactではリストの表示とかをするときに、リストの要素一つ一つにkey属性を指定しないといけないらしい。key属性は要素を一意に特定できるもののことです。
これはリストは以下の項目を変更する場合の備えで、Key属性がない状態ではReactは配列の変更を検知できないらしい。
結果、一つの要素が追加や削除されえただけでも、リスト全体を再生成しないといけないことになり、リスト項目が多いとそれがオーバーヘッドになる。

コードで見てみる

以下の配列をpropsで渡して確認してみます。

const books = [
{
isbn: '978-3-16-148410-0',
title: 'Learn React',
price: 29.99,
summary: 'A comprehensive guide to learning React.js from scratch.',
},
{
isbn: '978-1-23-456789-0',
title: 'Advanced React Patterns',
price: 39.99,
summary: 'Explore advanced patterns and techniques in React development.',
},
]

以下はIDが付与されていないコード。当然コンソールには「installHook.js:1 Each child in a list should have a unique “key” prop.」のエラーが出ています。

export default function App({ books }) {
  return(
    <ul>
      {
        books.map(book => (
          <li>
            <p>{book.title}</p>
            <p>{book.summary}</p>
            <p>{book.price}</p>
          </li>
        ))
      }
    </ul>
  );
}

以下のようにli要素にkey属性を追加してみました。

export default function App({ books }) {
  return(
    <ul>
      {
        books.map(book => (
          <li key={book.isbn}>
            <p>{book.title}</p>
            <p>{book.summary}</p>
            <p>{book.price}</p>
          </li>
        ))
      }
    </ul>
  );
}

解消!
ちなみにですが、map関数の引数にindexなどを設定し、それをkey属性に使用してもコンソールのエラー自体を消すことはできます。以下はkey属性にindexを指定したコードです。

export default function App({ books }) {
  return(
    <ul>
      {
        books.map((book, index) => (
          <li key={index}>
            <p>{book.title}</p>
            <p>{book.summary}</p>
            <p>{book.price}</p>
          </li>
        ))
      }
    </ul>
  );
}

でもこれ、警告自体は消えるのですがReact的にはあまりよくないらしいです。一見するとindexは一意なのですが、要素の追加や削除、ソートなどによって変化する可能性があるためです。なのでキー値は明示的に渡すのがいいっぽいですね。

コメント

タイトルとURLをコピーしました