Search code examples
arraysreactjslistkeyunique

Why doesn't `index` qualify as a unique key, when passed as part of props to a custom react component?


When I just list the items directly, using index works. As in the following.

        <ol className="item-list">
            {
                props.items.map((item, index) => (
                    <li key={index}>{item}</li>
                ))
            }
        </ol>

But when I create a custom component to represent the list item, using index doesn't seem to qualify as being unique... And I end up getting a warning, as in the following.

        <ol className="item-list">
            {
                props.items.map((item, index) => (
                    <ShoppingItem
                        index={index}
                        item={item}
                    />
                ))
            }
        </ol>

The ShoppingItem is a simple component, like the following.

        const ShoppingItem = props => (
            <li key={props.index}>{props.item}</li>
        );

And the warning I get in the console is the following.

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

Solution

  • You should read carefully the react docs for Lists and Keys: Extracting components with keys. The key goes on the component being mapped, not what it renders.

    Incorrect

    const ShoppingItem = props => (
      <li key={props.index}>{props.item}</li>
    );
    
    <ol className="item-list">
      {
        props.items.map((item, index) => (
          <ShoppingItem
            index={index}
            item={item}
          />
        ))
      }
    </ol>
    

    Correct

    <ol className="item-list">
      {
        props.items.map((item, index) => (
          <ShoppingItem
            key={index} // <-- key goes here
            item={item}
          />
        ))
      }
    </ol>