Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Each child in a list should have a unique "key", despite supplying unique keys

My component renders as follows:

if (!units) return '';
return (
  <div className = "learn">  
    {render(rootId)}
  </div>
);

Here is render (note recursion):

const render = (id) => {
  const unit = units[id];
  return (
    <>
    <div key={id} className={id}>{unit.title}</div>
    {/* No warning without the following line */}
    {unit.children.map(childId => render(childId))} 
    </>
  );
}

All ids are unique. To make sure, I added a className and here is the resulting html:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

enter image description here

Thus, it seems that all divs do have a unique key. Nonetheless, I get the warning Each child in a list should have a unique "key". What am I missing?

>Solution :

React key should be on the outer-most mapped element, the React Fragment in this case.

const render = (id) => {
  const unit = units[id];
  return (
    <Fragment key={id}>
      <div className={id}>{unit.title}</div>
      {unit.children.map(childId => render(childId))} 
    </Fragment>
  );
}

If you are rendering only the div then the key could remain there.

const render = (id) => {
  const unit = units[id];
  return (
    <div key={id} className={id}>{unit.title}</div>
  );
}

To avoid mounting/remounting issues you should redefine render to be a component instead. (per @DennisVash)

const RenderUnits = ({ id }) => {
  const unit = units[id];
  return (
    <>
      <div className={id}>{unit.title}</div>
      {unit.children.map(id => (
        <RenderUnits key={id} id={id} /> // <-- React key here
      ))}
    </>
  );
};

...

if (!units) return '';
return (
  <div className = "learn">  
    <RenderUnits id={rootId} />
  </div>
);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading