925

I'm building a React component that accepts a JSON data source and creates a sortable table.
Each of the dynamic data rows has a unique key assigned to it but I'm still getting an error of:

Each child in an array should have a unique "key" prop.
Check the render method of TableComponent.

My TableComponent render method returns:

<table>
  <thead key="thead">
    <TableHeader columns={columnNames}/>
  </thead>
  <tbody key="tbody">
    { rows }
  </tbody>
</table>

The TableHeader component is a single row and also has a unique key assigned to it.

Each row in rows is built from a component with a unique key:

<TableRowItem key={item.id} data={item} columns={columnNames}/>

And the TableRowItem looks like this:

var TableRowItem = React.createClass({
  render: function() {

    var td = function() {
        return this.props.columns.map(function(c) {
          return <td key={this.props.data[c]}>{this.props.data[c]}</td>;
        }, this);
      }.bind(this);

    return (
      <tr>{ td(this.props.item) }</tr>
    )
  }
});

What is causing the unique key prop error?

Brett DeWoody
  • 55,478
  • 28
  • 131
  • 182
  • 10
    Your rows in JS array should have unique `key` property. It'll help ReactJS to find references to the appropriate DOM nodes and update only content inside mark-up but not re-render the whole table/row. – Kiril Feb 04 '15 at 19:09
  • 1
    Can you also share `rows` array or more preferably a jsfiddle? You dont need a `key` property on `thead` and `tbody` by the way. – nilgun Feb 04 '15 at 19:12
  • I added the row component to the original question @nilgun. – Brett DeWoody Feb 04 '15 at 19:15
  • 3
    Is it possible that some items do not have an id or have same id? – nilgun Feb 04 '15 at 19:16

23 Answers23

843

You should add a key to each child as well as each element inside children.

This way React can handle the minimal DOM change.

In your code, each <TableRowItem key={item.id} data={item} columns={columnNames}/> is trying to render some children inside them without a key.

Check this example.

Try removing the key={i} from the <b></b> element inside the div's (and check the console).

In the sample, if we don't give a key to the <b> element and we want to update only the object.city, React needs to re-render the whole row vs just the element.

Here is the code:

var data = [{name:'Jhon', age:28, city:'HO'},
            {name:'Onhj', age:82, city:'HN'},
            {name:'Nohj', age:41, city:'IT'}
           ];

var Hello = React.createClass({
    
    render: function() {
            
      var _data = this.props.info;
      console.log(_data);
      return(
        <div>
            {_data.map(function(object, i){
               return <div className={"row"} key={i}> 
                          {[ object.name ,
                             // remove the key
                             <b className="fosfo" key={i}> {object.city} </b> , 
                             object.age
                          ]}
                      </div>; 
             })}
        </div>
       );
    }
});
 
React.render(<Hello info={data} />, document.body);

The answer posted by @Chris at the bottom goes into much more detail than this answer.

React documentation on the importance of keys in reconciliation: Keys

Liam
  • 25,247
  • 27
  • 110
  • 174
jmingov
  • 12,785
  • 2
  • 32
  • 37
  • I added the component you're talking about to the original question. – Brett DeWoody Feb 04 '15 at 20:16
  • Should I be adding a `key` to the `` element? – Brett DeWoody Feb 04 '15 at 20:17
  • added extra info again nif it helps. – jmingov Feb 04 '15 at 20:24
  • 1
    That doesn't fix it either. I added a key to the `` elements in `TableRowItem` and still get the error. I feel the error message would be different if the issue was within `TableRowItem` too. I originally did have the same error, but it referenced the `TableRowItem` component. I fixed that by adding the `key` as a property of the component. The error is now referring to the `TableComponent`. – Brett DeWoody Feb 04 '15 at 20:24
  • im tryng a fiddle with your code, is {this.props.data[c]} plain text? – jmingov Feb 04 '15 at 20:45
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/70260/discussion-between-3boll-and-brett-dewoody). – jmingov Feb 04 '15 at 20:50
  • 6
    I am running into the exact same error. Was this resolved after the chat? If so, can you please post an update to this question. – Deke Feb 26 '16 at 23:04
  • 1
    The answer works, Deke. Just make sure that `key` value for the prop is unique for each item and you're putting the `key` prop to the component which is closest to array boundaries. For example, in React Native, first I was trying to put `key` prop to `` component. However I had to put it to `` component which is parent of ``. if Array == [ (View > Text), (View > Text)] you need to put it to View. Not Text. – scaryguy Jul 28 '16 at 00:52
  • 403
    Why is is so hard for React to generate unique keys itself? – Davor Lucic Aug 09 '16 at 13:16
  • 15
    @DavorLucic, here is a discussion: https://github.com/facebook/react/issues/1342#issuecomment-39230939 – koddo Oct 06 '16 at 11:40
  • 6
    [This is pretty much the official word](https://facebook.github.io/react/docs/lists-and-keys.html#keys) on a note made in the issue chat linked to above: keys are about identity of a member of a set and auto-generation of keys for items emerging out of an arbitrary iterator probably has performance implications within the React library. – sameers Jan 11 '17 at 22:05
  • should this key be unique only in that array or should be unique in the whole App? – farmcommand2 Mar 09 '18 at 15:17
  • 1
    @farmcommand2 "The key only has to be unique among its siblings, not globally unique." as per : https://reactjs.org/docs/reconciliation.html#keys – SherylHohman Mar 13 '18 at 09:55
  • Linked to Codepen does not compile/run. – SherylHohman Mar 13 '18 at 09:56
  • 5
    Is there documentation explaining why not only the child nodes need a unique key, but also the _children_ of those child nodes? I couldn't find anything about that specifically in the docs. – Michael Martin-Smucker May 26 '18 at 00:15
  • This requires more emphasis: "Keys only make sense in the context of the surrounding array. For example, if you extract a ListItem component, you should keep the key on the elements in the array rather than on the
  • element in the ListItem itself." -- https://reactjs.org/docs/lists-and-keys.html#extracting-components-with-keys
  • – Day Davis Waterbury Jun 04 '19 at 20:59
  • Except that this example uses index as key which causes another React error: `Do not use Array index in keys` – geoidesic Aug 08 '19 at 16:57
  • 1
    Genious! Thank you for exaplaining! – tonysepia Aug 28 '19 at 20:38
  • to broad code example that it's difficult to see that you just need to add `key={i}` inside your mapping tag to fix the issue. – Wotori Movako Jun 03 '22 at 18:47