Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React - Each child in array .. unique "key" prop warning

I appear to have a decent understanding of this principal, which allows me to get by, until now. I am applying a key prop to all children of all iterators, and yet I'm still getting this warning.

A FacilitiesContainer is rendering a FacilitiesComponent, which in turn renders a list of Facilities, which renders a list of Courses. A Course does not use an iterator. However, the FacilitiesContainer is passing the FacilitiesComponent through a HOC, which is returning the final component. There's nothing in the HOC that modifies the passed components, so I'm not sure if this is a problem.

// The render method of FacilitiesContainer 
render = () => {
    let FacilitiesWithSearch = SearchHOC(
      BasicSearch, 
      FacilitiesComponent, 
      {data: this.state.facilities }
    );
    return <FacilitiesWithSearch />;
  }


class FacilitiesComponent extends Component {
  renderFacilities = () => (
    this.props.data.map((facilityData, index) =>
      <Facility key={index} data={facilityData} />
    )
  )

  render = () => (
    <Grid>
      <Row>
        <Col xs={12} sm={8} smOffset={2} md={8} mdOffset={1}>
          {
            this.props.data.length > 0
              ? this.renderFacilities()
              : <div>No results</div>
          }
        </Col>
      </Row>
    </Grid>
  )
}

const Facility = ({ data }) => (
  <Panel>
    <Panel.Heading>
      <Panel.Title>{data.Name}</Panel.Title>
    </Panel.Heading>
    <Panel.Body>
      <Grid>
        <Row>
          <p><b>Address:</b><br />
            {data.Street}<br />
            {data.City}, {data.State} {data.Zip}
          </p>
          <p><b>Phone:</b> {data.Phone}</p>
            {
              data.Courses.map((courseData, index) =>
                <p><Course key={index} data={courseData} /></p>)
            }
        </Row>
      </Grid>
    </Panel.Body>
  </Panel>
);
like image 493
Firephp Avatar asked Dec 23 '22 08:12

Firephp


2 Answers

You indeed didn't provide keys to p elements here:

{
  data.Courses.map((courseData, index) =>
    <p><Course key={index} data={courseData} /></p>)
}

Should be

{
  data.Courses.map((courseData, index) =>
    <p key={index}><Course data={courseData} /></p>)
}
like image 178
dfsq Avatar answered Jan 10 '23 10:01

dfsq


Try to append a string to the index before assigning it to the key. That's because you are only using index (0,1,2...) both for your list of facilities and list of courses, so there will be duplicated indexes in the final rendered component. If you do as below you ensure that each index is unique:

<Facility key={`facility_${index}`} data={facilityData} />

and

<Course key={`course_${index}`} data={courseData} />
like image 31
Guilherme Lemmi Avatar answered Jan 10 '23 09:01

Guilherme Lemmi