1024

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
  • 59,771
  • 29
  • 135
  • 184
  • 13
    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

28 Answers28

911

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:

const data = [
  { name: "Nuri", age: 28, city: "HO" },
  { name: "Talib", age: 82, city: "HN" },
  { name: "Jenny", age: 41, city: "IT" },
];

const ExampleComponent = React.createClass({
  render: function () {
    const infoData = this.props.info;
    return (
      <div>
        {infoData.map((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(<ExampleComponent 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

zero_cool
  • 3,960
  • 5
  • 39
  • 54
jmingov
  • 13,553
  • 2
  • 34
  • 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
  • 466
    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
  • 6
    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
  • 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
  • In general you should not use the array index as the key — it loses all benefit if you reorder the array — instead use a unique feature of the data inside the array. – Quentin Jul 03 '22 at 09:53
  • This is a fundamental design error in React. it should not be up to the caller to generate such keys. If React needs a unique key to track the item in the DOM, fine...it should generate it. Apologies that this doesn't actually give a solution...it's getting uncomfortable living with React with so many elephants in the room. – Midiman Jul 31 '23 at 10:06