10
votes

I'm getting that error, but I'm defining a key. Here's my App.js that it's complaining about.

import React from 'react';
import Relay from 'react-relay';
import AccountTable from './AccountTable';

class App extends React.Component {
  render() {
    return (
      <div>
        <h1>Account list</h1>
          {this.props.viewer.accounts.edges.map(edge =>
            <AccountTable key={edge.node.id} account={edge.node} />
          )}
      </div>
    );
  }
}

export default Relay.createContainer(App, {
    fragments: {
        viewer: () => Relay.QL`
            fragment on User {
                accounts(first: 10) {
                    edges {
                        node {
                            ${AccountTable.getFragment('account')}
                        }
                    }
                }
            }
        `,
    },
});
2
bob ross would be proud of your code mountains. But really you should check the uniqueness of your edge.node.id's.aaaaaa
do the usual sanity checks I guess. Is the above code the 100% source of the error? are the ids actually unique? maybe you have a couple of undefineds / nullsazium
See if you have duplicate IDs: console.log(this.props.viewer.accounts.edges.map(edge => edge.node.id))sdgluck
So, it turns out the edge.node object does not have an id defined at this point. I think it's because the node references another fragment. I didn't have this problem when I had accounts just spelled out inside this fragment. This showed up when I broke the account graphql stuff out into it's own fragment. Do any of you know a work around?LoneWolfPR

2 Answers

10
votes

The easiest way to correct this is to base the key off the index of the map:

{this.props.viewer.accounts.edges.map((edge, i) =>
    <AccountTable key={i} account={edge.node} />
)}

Then, you don't have to worry about how unique the value of edge.node.id is. The key only needs to be unique in the context of all the AccountTable siblings. It doesn't need to be globally unique. So, the index works well.

However, if you have a stable id that is based off of the object, that is obviously better.

0
votes

The solution I use is to extract the underlying id of relay fragment as key

{this.props.viewer.accounts.edges.map((edge) =>
    edge && e.node && <AccountTable key={edge.node.__id} account={edge.node} />
)}