marmelab / react-admin

A frontend Framework for single-page applications on top of REST/GraphQL APIs, using TypeScript, React and Material Design
http://marmelab.com/react-admin
MIT License
24.77k stars 5.22k forks source link

<AutocompleteInput /> Error each child in a list should have a unique "key" prop. #8402

Open hs-dev-web opened 1 year ago

hs-dev-web commented 1 year ago

This is my setting for the element:

const [choices, setChoices] = useState([]);

<AutocompleteInput
      onCreate={() => {
        const newCategoryName = prompt("Example: 2 - Assets");
        const split = newCategoryName.split("-"); // ["2 ", " Assets"]
        const num = +split[0].replace(/\D/g, ""); // 2
        const newCategory = {
          code: num, // 2
          name: newCategoryName, // 2 - Assets
        };
        setChoices((prev) => [...prev, newCategory]);
        return newCategory;
      }}
      choices={choices}
      optionValue="code"
      {...props}
    />

The first time I type inside AutocompleteInput and then click anywhere outside of it (so that the component get blured) it throws an error warning like this:

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

Check the render method of ForwardRef(Autocomplete).

slax57 commented 1 year ago

Could you please follow the issue template and provide a reproduction sandbox?

mikhail-fedosenko commented 3 weeks ago

@slax57 I've found same issue while working with React-Admin v4. I've reproduced it both for v4 and v5. It seems that AutocompleteInput doesn't support any other optionValue than id when create or onCreate is used. The root cause is hardcoded item data structure in useSupportCreateSuggestion: https://github.com/marmelab/react-admin/blob/6472e3af0a8b06e3168a19f3b30115b8b4c6f7f2/packages/ra-ui-materialui/src/input/useSupportCreateSuggestion.tsx#L73

Links to sandboxes:

Steps:

  1. Login to Admin sandbox.
  2. Go to Posts.
  3. Press "Create".
  4. Mouse click in "test autocomplete" input.

Actual result: Warning: Each child in a list should have a unique "key" prop is displayed.

Workaround: use optionValue="id" for AutocompleteInput (and change the data structure of choices).

Test code:

const testChoices = [
  { label: 'item 1', value: 1, id: 1 },
  { label: 'item 2', value: 2, id: 2 },
  { label: 'item 3', value: 3, id: 3 },
];

// ...

<AutocompleteInput
  source="testValue"
  label="Test autocomplete"
  optionText="label"
  optionValue="value"
  // Comment the line above and uncomment the line below to fix key prop warning
  //   optionValue="id"
  choices={testChoices}
  onCreate={(filter) => {
    const nextValue =
      [...testChoices].sort((a, b) => b.value - a.value)[0].value + 1;

    const newChoice = {
      label: filter ?? '',
      value: nextValue,
      id: nextValue,
    };

    testChoices.push(newChoice);

    return newChoice;
  }}
/>
slax57 commented 3 weeks ago

Hi @mikhail-fedosenko

Thanks to your detailed report I could reproduce the issue, and confirm the analysis. I agree the bug seems to be located in useSupportCreateSuggestion.

Would you like to open a PR to fix it?

Thanks!