Search code examples
reactjsantd

Each record in table should have a unique `key` prop,or set `rowKey` to an unique primary key


I am rendering a table with ant design and it works fine, but there is a warning in the console:

Each record in table should have a unique key prop,or set rowKey to an unique primary key

My code is as follows:

import React, { Component } from 'react';
import {  Table} from 'antd';
import { adalApiFetch } from '../../adalConfig';


class ListTenants extends Component {

    constructor(props) {
        super(props);
        this.state = {
            data: []
        };
    }



    fetchData = () => {
        adalApiFetch(fetch, "/Tenant", {})
          .then(response => response.json())
          .then(responseJson => {
            if (!this.isCancelled) {
                const results= responseJson.map(row => ({
                    ClientId: row.ClientId,
                    ClientSecret: row.ClientSecret,
                    Id: row.Id,
                    SiteCollectionTestUrl: row.SiteCollectionTestUrl,
                    TenantDomainUrl: row.TenantDomainUrl
                  }))
              this.setState({ data: results });
            }
          })
          .catch(error => {
            console.error(error);
          });
      };


    componentDidMount(){
        this.fetchData();
    }

    render() {
        const columns = [
                {
                    title: 'Client Id',
                    dataIndex: 'ClientId',
                    key: 'ClientId'
                }, 
                {
                    title: 'Site Collection TestUrl',
                    dataIndex: 'SiteCollectionTestUrl',
                    key: 'SiteCollectionTestUrl',
                },
                {
                    title: 'Tenant DomainUrl',
                    dataIndex: 'TenantDomainUrl',
                    key: 'TenantDomainUrl',
                }
        ];



        return (
            <Table columns={columns} dataSource={this.state.data} />
        );
    }
}

export default ListTenants;

Solution

  • React renders lists using the key prop. It works so because react allows you to reduce the complexity of diffing algorithms and reduce the number of DOM mutations. You can read a bit more in react reconciliation docs: https://reactjs.org/docs/reconciliation.html

    In your case, you added the keys to the columns, but not for rows. Add the key field to the data source. So your code could be the following:

    import React, { Component } from 'react';
    import {  Table} from 'antd';
    import { adalApiFetch } from '../../adalConfig';
    
    
    class ListTenants extends Component {
    
        constructor(props) {
            super(props);
            this.state = {
                data: []
            };
        }
    
    
    
        fetchData = () => {
            adalApiFetch(fetch, "/Tenant", {})
              .then(response => response.json())
              .then(responseJson => {
                if (!this.isCancelled) {
                    const results= responseJson.map(row => ({
                        key: row.id, // I added this line
                        ClientId: row.ClientId,
                        ClientSecret: row.ClientSecret,
                        Id: row.Id,
                        SiteCollectionTestUrl: row.SiteCollectionTestUrl,
                        TenantDomainUrl: row.TenantDomainUrl
                      }))
                  this.setState({ data: results });
                }
              })
              .catch(error => {
                console.error(error);
              });
          };
    
    
        componentDidMount(){
            this.fetchData();
        }
    
        render() {
            const columns = [
                    {
                        title: 'Client Id',
                        dataIndex: 'ClientId',
                        key: 'ClientId'
                    }, 
                    {
                        title: 'Site Collection TestUrl',
                        dataIndex: 'SiteCollectionTestUrl',
                        key: 'SiteCollectionTestUrl',
                    },
                    {
                        title: 'Tenant DomainUrl',
                        dataIndex: 'TenantDomainUrl',
                        key: 'TenantDomainUrl',
                    }
            ];
    
    
    
            return (
                <Table columns={columns} dataSource={this.state.data} />
            );
        }
    }
    
    export default ListTenants;