0

Trying to render some values in a simple react component I get this error

 Each child in an array or iterator should have a unique "key" prop. Check the render method of `Abstractfactory`. See react-warning-keys for more information.
    in div (created by Abstractfactory)
    in Abstractfactory


class Customer{  
    public id: string;
    public firstName: string;
    public lastName: string;
}

export default Customer;

import * as React from 'react';
import { IAbstractFactoryProps } from "./IAbstractFactoryProps";  
import { IAbstractFactoryState } from "./IAbstractFactoryState";  
import styles from './Abstractfactory.module.scss';
import { escape } from '@microsoft/sp-lodash-subset';
import DaoFactory from "./DaoFactory";  
import ICustomerDao from "./ICustomerDao";  
import DataSources from "./DatasourcesEnum";

export default class Abstractfactory extends React.Component<IAbstractFactoryProps, IAbstractFactoryState> {
  //Private instance of customerDao, please note it returns ICustomerDao, an Interface,
    //not a concrete type
    private customerDao: ICustomerDao;

    constructor(props: IAbstractFactoryProps, state: IAbstractFactoryState) {
      super(props);
      this.setInitialState();

      // We set the Dao depending on the selected data source
      this.setDaos(props.datasource);

      //Then we set the list of customers and note, we dont care if they come from Sharepoint
      //Rest API or anything else.
      this.state = {
        items: this.customerDao.listCustomers(),
      };
    }

    public render(): React.ReactElement<IAbstractFactoryProps> {
      return (
        <div className={ styles.abstractfactory }>
          <div className={ styles.container }>
            <div className={ styles.row }>
              <div className={ styles.column }>
                  {this.state.items.map( i => (<div>i.id</div>))}
               </div>
            </div>
          </div>
        </div>
      );
    }

    public setInitialState(): void {
      this.state = {
        items: []
      };
    }

    private setDaos(datasource: string): void {
      const data: DataSources = datasource === "Sharepoint" ? DataSources.SharepointList : DataSources.JsonData;
      this.customerDao = DaoFactory.getDAOFactory(data).getCustomerDAO();

      //Now, its transparent for us a UI developers what datasource was selected
      //this.customerDao.
    }
}
Luis Valencia
  • 32,619
  • 93
  • 286
  • 506
  • 2
    Possible duplicate of [Understanding unique keys for array children in React.js](https://stackoverflow.com/questions/28329382/understanding-unique-keys-for-array-children-in-react-js) – Matsemann May 30 '18 at 21:45

1 Answers1

1

Since you are mapping over state.items, each of the <div> tags you output need to have a unique key property, so that React can internally tell them apart:

public render(): React.ReactElement<IAbstractFactoryProps> {
  return (
    <div className={ styles.abstractfactory }>
      <div className={ styles.container }>
        <div className={ styles.row }>
          <div className={ styles.column }>
              {this.state.items.map( i => (<div key={i.id}>i.id</div>))}
           </div>
        </div>
      </div>
    </div>
  );
}
ouni
  • 3,233
  • 3
  • 15
  • 21
  • so thats always needed every time there is a collection? – Luis Valencia May 30 '18 at 21:54
  • 1
    Yes, otherwise React won't know what to do when one or more of the items is changed, and you may see "dancing" or other odd behavior. You can always use the array index from `map`, if your data doesn't have built-in identifiers. – ouni May 30 '18 at 22:06