R.Dixon
R.Dixon

Reputation: 107

react not using supplied key prop

I have a fuzzy search test running at https://codesandbox.io/s/cranky-faraday-ucilw?file=/src/App.js

However, it is not accepting the unique key prop even though I am passing in a unique ID.

What am I doing wrong?

Here is the error:

Warning: Each child in a list should have a unique "key" prop.

Check the render method of `MyComponent`. 
    in ul (at search.jsx:25)
    in MyComponent (at App.js:13)
    in div (at App.js:12)
    in App (at src/index.js:9)
    in StrictMode (at src/index.js:8)

App.js Code:

import React, { Component } from "react";
import MyComponent from "./search";

const customers = [
  { id: "1", name: "Bob", email: "[email protected]" },
  { id: "2", name: "Foo", email: "[email protected]" }
];

export default class App extends Component {
  render() {
    return (
      <div>
        <MyComponent customers={customers} />
      </div>
    );
  }
}

Search.js Code:

import React from "react";
import useFuse from "react-use-fuse";

function MyComponent({ customers }) {
  const options = {
    keys: ["name", "email"]
  };

  const { result, search, term } = useFuse({
    data: customers,
    options
  });

  return (
    <div>
      <input
        onChange={e => search(e.target.value)}
        value={term}
        placeholder="Search for a customer..."
      />

      {console.log(term)}
      {result &&
        result.map(customers => (
          <ul key={customers.id}>
            <li>{customers.name}</li>
            <li>{customers.email}</li>
          </ul>
        ))}
    </div>
  );
}

export default MyComponent;

Upvotes: 0

Views: 53

Answers (2)

Rob Brander
Rob Brander

Reputation: 3781

The error message "Warning: Each child in a list should have a unique 'key' prop." means that each 'li' in your code should have a key. In this case you can fix this by making a composite key combining the id with the field names

example:

<ul key={customers.id}>
  <li key={`${customers.id}-name`}>{customers.name}</li>
  <li key={`${customers.id}-email`}>{customers.email}</li>
</ul>

Upvotes: 0

HermitCrab
HermitCrab

Reputation: 3274

The problem is with your result array which structure changes when you filter it.

Unfiltered:

[{id, name, email}, ...]

Filtered:

[{ item: {id, name, email } }, ...]

So when you map result, there are no id hence the error message.

One way to fix this is to check if the objects returned by map have a property called item:

  {result &&
    result.map(customer => {
      if (customer.item) customer = customer.item;
      return (
        <div key={customer.id}>
          <p>{customer.name}</p>
          <p>{customer.email}</p>
        </div>
      );
    })}

By the way, I renamed customers in map to customer, because customers is already declared as props

Upvotes: 1

Related Questions