38

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;
Luis Valencia
  • 32,619
  • 93
  • 286
  • 506

12 Answers12

49

Just add a unique key value in tag link this:

   <Table
   columns={columns}
   dataSource={this.state.data} 
   rowKey="Id" />  // unique key

Hope this help

Jhon
  • 519
  • 1
  • 3
  • 3
  • 1
    You can also set a function for rowKey to make every cell unique: ```rowKey={(record) => record.name}``` – Jobeso Jan 19 '23 at 20:28
24

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;
Nik
  • 2,170
  • 1
  • 14
  • 20
  • Thanks, I always wanted to understand why every data-grid/table api required we give a key for every row. It didn't make sense for me since I thought they could just create one internally based on the array index for each row element. – ta32 Nov 20 '22 at 02:09
  • I have a post published on medium it might help you with more content about react keys: https://medium.com/@xnim/keys-in-react-715568626c3 – Nik Nov 26 '22 at 12:04
15

React Table unique key / rowKey

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

solution 1

each col has a unique key

// each column with unique key

import React from 'react';

import {
  Table,
} from 'antd';

const leftTableColumns = [
  {
    title: 'Page / Modal',
    dataIndex: 'pageModal',
    key: 'pageModal',
  },
  {
    title: 'Success Rate',
    dataIndex: 'successRate',
    key: 'successRate',
  },
];

const LeftTable = (props) => {
  const {
    leftTableDatas,
  } = props;
  return (
    <>
      <Table
        columns={leftTableColumns}
        dataSource={leftTableDatas}
      />
    </>
  );
};

export {
  LeftTable,
};

export default LeftTable;


solution 2

only need set rowkey on the table with the unique value

// table with rowkey

import React from 'react';

import {
  Table,
} from 'antd';

const leftTableColumns = [
  {
    title: 'Page / Modal',
    dataIndex: 'pageModal',
  },
  {
    title: 'Success Rate',
    dataIndex: 'successRate',
  },
];

const LeftTable = (props) => {
  const {
    leftTableDatas,
  } = props;
  return (
    <>
      <Table
        // shorthand rowKey
        rowKey="id"
        // rowKey={obj => obj.id}
        columns={leftTableColumns}
        dataSource={leftTableDatas}
      />
    </>
  );
};

export {
  LeftTable,
};

export default LeftTable;


ref

https://ant.design/components/table/

image

Diamond
  • 3,470
  • 2
  • 19
  • 39
xgqfrms
  • 10,077
  • 1
  • 69
  • 68
5

only you need set rowkey on the table with the unique value.


 <Table
  dataSource={[finance]}
  columns={columns}
  rowKey={record => record.id}
 />
Angham Aabed
  • 51
  • 1
  • 1
4

Because you are not adding key to dataSource array, add a key in that also.

Like this:

const results= responseJson.map(row => ({

    key: row.ClientId,     // here

    ClientId: row.ClientId,
    ClientSecret: row.ClientSecret,
    Id: row.Id,
    SiteCollectionTestUrl: row.SiteCollectionTestUrl,
    TenantDomainUrl: row.TenantDomainUrl
}))

Or you can use any unique value of dataSource array as key by using property rowKey, like this:

<Table
   columns={columns}
   dataSource={this.state.data}

   rowKey="Id" />     // any unique value

Doc Reference.

Mayank Shukla
  • 100,735
  • 18
  • 158
  • 142
3

for me worked this solution

rowKey="{record => record.id}"

or rowKey="id"

but in your collection have to exist the id column

3

I had your problem and this method answered

<Table 
  columns={columns} 
  dataSource={data} 
  rowKey="name" 
/>
2

I have the same issue but solved with this, Hope this help :) just add rowKey='id' I use rowKey = 'id' because 'id' is unique data in variable dataSource, but you can use another unique value from variable dataSource. (with unique value)

import React from 'react'
import { Table } from 'antd' 

const committeInformation = () => {

 const columns = [
  {
    key: '0',
    title: 'id',
    dataIndex: 'id',
  },
  {
    key: '1',
    title: 'name',
    dataIndex: 'name',
  },
  {
   key: '2',
   title: 'email',
   dataIndex: 'email'
  }
 ]

 const dataSource = [
   {
     id: '1',
     name: 'user 1',
     email: 'coco@gmail.com',
     
   },
   {
     id: '2',
     name: 'user 2',
     email: 'coco@gmail.com'
    }
  ]

  return (
    <Table
     rowKey='id' //this from variable dataSource
     columns={columns}
     dataSource={dataSource}
    />
  )
}

 export default committeInformation
1

Fast hack

I do assign random math numbers changed to string on each key.?

This is to say my columns become

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

Hope this helps anybody visiting from the future..........

emanuel sanga
  • 815
  • 13
  • 17
0

If your data has no logical key and you only need the key for presentation purposes, you could intercept the data and write a key in using a random number.

export const Table = ({
  data,
}: {
  data: ITableData[] | undefined;
}) => {

 ....

 if (data) {
data.map((record) => {
  return (record.id = Math.floor(Math.random() * 1000000));
});

and then assign the rowkey to the table

<Table dataSource={data} rowKey="id">
ben_g_123
  • 108
  • 5
0

in Vue 3:

<a-table
    ...
    :columns="yourColumns"
    :data-source="yourData"
    // the solution:
    :row-key="record => record.id"
    // or
    :rowKey="record => record.id"
  >
ValeronS
  • 11
  • 2
0

This solution is specific to 'antd'

If the error says:
Check the render method of Body:

You can set the rowKey a unique value. It can take both string or a function that returns a unique value.

  <Table
     columns={columns}
     dataSource={[]}
     rowKey="id"
    />

If the error says:
Check the render method of Cell:

This could mean that you are rendering a list of values in one of the CELLS. You can add a key to each of the item in the list and get the problem solved!