0

I have this warning but I consult this page from Facebook: Warning: Each child in a list should have a unique "key" prop.
This is my error log in console

I'm using React JS and I have a component named Card which is a child from Carousel and a child from Categories

<Categories title='Gifs'>
      <Carousel>
        {
          productList.map((item) => <Card product={item} key={item.id} />)
        }
      </Carousel>
</Categories>

This is how my homepage looks:

import React from 'react';
import Categories from '../components/Categories';
import Carousel from '../components/Carousel';
import Card from '../components/Card';
import Lead from '../components/Lead';
// import firebase from '../firebase';

import '../assets/styles/App.scss';
import { productList, randomProduct } from '../api/request';

class Homepage extends React.Component {

  constructor(props) {
    super(props);
    console.log('Primero inicia el constructor');
    this.state = {
      productList: [],
      randomProduct: {},
    };
  }

  componentDidMount() {
    productList().then((productList) => this.setState({ productList }));
    randomProduct().then((randomProduct) => this.setState({ randomProduct }));
  }

  componentDidUpdate() {
    console.log('quinto actualiza los datos');
  }

  componentWillUnmount() {
    console.log('sexto desmuenta el componente --> lo elimina');
    clearTimeout(this.timeoutId);
  }

  render() {
    console.log('Segundo y Cuarto verifica que hay cambios por lo cual vuelve a reenderizar');
    const { productList, randomProduct } = this.state;
    return (
      <div className='App'>
        <Lead product={randomProduct} />
        <Categories title='Textiles'>
          <Carousel>
            {
              productList.map((item) => <Card product={item} key={item.id} />)
            }
          </Carousel>
        </Categories>
        <Categories title='Artesanias'>
          <Carousel>
            {
              productList.map((item) => <Card product={item} key={item.id} />)
            }
          </Carousel>
        </Categories>
        <Categories title='Gifs'>
          <Carousel>
            {
              productList.map((item) => <Card product={item} key={item.id} />)
            }
          </Carousel>
        </Categories>
      </div>
    );
  }
}

export default Homepage;

This is how my Card component looks:

import React, { useEffect, useState } from 'react';
import '../assets/styles/components/Card.scss';
import { LoadingRectangles } from './LoadingSpiners';

const Card = ({ product }) => {

  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    // if (product.id) {
    //   console.log(` el product id es: ${product.id}`);
    //   setIsLoading(false);
    // }
    setIsLoading(false);
  }, [product]);

  return (
    <div className='card'>
      { isLoading ? <LoadingRectangles /> :
        (
          <div>
            <img className='card__img' src={product.photo1} alt={product.name} />
            <div className='card__details'>
              <div>
                <img className='card__details--img' src='' alt='icon' />
              </div>
              <p className='card__details--title'>
                {product.name}
              </p>
              <p className='card__details--subtitle'>
                {product.cost}
              </p>
            </div>
          </div>
        )}
    </div>
  );
};

export default Card;

This is my Carousel:

import React from 'react';

import '../assets/styles/components/Carousel.scss';

const Carousel = ({ children }) => (
  <section className='carousel'>
    <div className='carousel__container'>
      {children}
    </div>
  </section>
);

export default Carousel;

And this is my Categories:

import React from 'react';
import '../assets/styles/components/Categories.scss';

const Categories = ({ children, title }) => (
  <div className='categories'>
    <h3 className='categories__title'>{title}</h3>
    {children}
  </div>
);

export default Categories;

Facebook React documentation show this example. I can't see the difference between this and my code. It looks the same to me...

function ListItem(props) {
  // Correct! There is no need to specify the key here:
  return <li>{props.value}</li>;
}

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    // Correct! Key should be specified inside the array.
    <ListItem key={number.toString()} value={number} />
  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);
Nisse Engström
  • 4,738
  • 23
  • 27
  • 42
  • 1
    Does this answer your question? [Understanding unique keys for array children in React.js](https://stackoverflow.com/questions/28329382/understanding-unique-keys-for-array-children-in-react-js) – AndrewL64 Jun 20 '20 at 19:33

2 Answers2

1

Each child in a list should have a UNIQUE "key" prop.
But you have 3 lists and you use the same key every time.

You could prefix each key with Textiles, Gifs etc. in order to be sure that they are unique, like key={'textile-' + item.id}

Arnaud Claudel
  • 3,000
  • 19
  • 25
  • if i change like you say should be like this ` { productList.map((item) => ) } ` but i have this new warning **Warning: Encountered two children with the same key, `textile-undefined`. Keys should be unique so that components maintain their identity across** – Elvis Ojeda Melo Jun 20 '20 at 19:58
  • Well, it just means that some of your `ids` are `undefined`, I can't change your data. Try to find a reliable source of unique values for each item. – Arnaud Claudel Jun 20 '20 at 20:31
0

Sorry guys, thanks for your help. I'm looking why I have that warning and I discover it.

I didn't have the field product.id. I'm using Firestore and my docs looks like this: my firestore doc

I was thinking that I have the field id but I didn't. :P

Nisse Engström
  • 4,738
  • 23
  • 27
  • 42