0

As my first react project, I decided to try and make a Pokedex. I have an array of Pokemon and that I pass into a List component and use the .map() function to render. I understand that the root-most element of that the .map() function returns needs a unique key and I understand that it is ideal if the key can be truly unique to the item so that if the list is sorted, items have the same key. Therefore, I figured using the 'id' of the pokemon would be ideal. I believe I have done that but I cannot get rid of the warning in console. I'd really appreciate a hand with this.

export default class List extends React.Component {
  render() {
    const { list, nav } = this.props;
    return (
      <div className="list">
        {list.map((pokemon) => (
          <PokemonItem key={pokemon.id} navigation={nav} pokemon={pokemon} />
        ))}
      </div>
    );
  }
}

PokemonItem Render Method

render() {
    const { pokemon, navigation } = this.props;
    return (
      <div onClick={() => {
          navigation.navigate("Details", { pokemon });
        }}
        className={"list-item bg_" + pokemon.types[0]}>
        <div className="header">
          <div className="name">{pokemon.name}</div>
          <div className="id">#{this.getId(pokemon.id)}</div>
        </div>
        <div className="body">
          <div className="types">
            {pokemon.types.map((type) => {
              return <div className="type">{type}</div>;
            })}
          </div>
          <div className="sprite">
            <img src={pokemon.imgURL} alt={pokemon.name} title={pokemon.name}></img>
          </div>
        </div>
        <div className="background-image">
          <img src={PkBall} alt="" />
        </div>
      </div>
    );
  }

Warning message showing in console

  • 1
    Try rendering something simpler than a `PokemonItem`, such as a `div`, and see if the problem persists. If so, you probably have a duplicate `id` (please, check your array). Otherwise, the problem is inside `PokemonItem`. – Rafael Tavares Oct 21 '21 at 19:54
  • or simple put index as key – Abu Sufian Oct 21 '21 at 19:55
  • 1
    @AbuSufian Using `index` as a key wouldn't be a smart choice, it would only "silence" the warning, and not solve the issue. Please, read [the docs](https://reactjs.org/docs/lists-and-keys.html). – Rafael Tavares Oct 21 '21 at 19:57
  • It would be nice if you could post the exact message and stacktrace in your console so the best solution can be suggested. – Cristian Torres Oct 21 '21 at 19:58
  • 1
    `pokemon.types` is mapped without passing a `key` prop to the `div` – Rafael Tavares Oct 21 '21 at 20:02
  • @RafaelTavares Although its probably not the best way to do it, pokemon.types is only used to determine CSS classes at this stage. Does that also affect the way react identifies elements? – BruceTheBrick Oct 21 '21 at 20:05
  • Yes Bruce. Your question is essentially a duplicate of [Understanding unique keys for array children in React.js](https://stackoverflow.com/a/43892905/8839059) (that's why I didn't post an answer). React needs a `key` due to the [Reconcilition algorithm](https://reactjs.org/docs/reconciliation.html) - read this doc's link, it's well written and I really recommend it to understand how keys affect the rendering process. – Rafael Tavares Oct 21 '21 at 20:10
  • @RafaelTavares Makes complete sense. Thanks for your help, I appreciate it! – BruceTheBrick Oct 21 '21 at 20:14

2 Answers2

0

After the edit of the OP's question the warning occurs here:

<div className="types">
            {pokemon.types.map((type) => {
              return <div className="type">{type}</div>;
            })}
</div>

The key-property is not set for div and should be done like in the first method. If type is unique you can use this as key.

Auskennfuchs
  • 1,577
  • 9
  • 18
0

Checking your PokemonItem it reveals that the reason may be laying in this piece of code:

{pokemon.types.map((type) => {
    return <div className="type">{type}</div>;
})}

This is easily fixed by adding the key attribute:

{pokemon.types.map((type) => {
    return <div className="type" key={type.id}>{type}</div>;
})}

You need to add a key in every item returned from a map in order to avoid this error. Also I advice you to add the console output related to your question in the body so it's easier to pinpoint the errors.

Cristian Torres
  • 256
  • 3
  • 12