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.73k stars 5.21k forks source link

Infinite re-rendering using disabled AutocompleteArrayInput in a ReferenceArrayInput #9714

Closed Nitix closed 5 months ago

Nitix commented 5 months ago

What you were expecting:

An stable page with a An AutocompleteArrayInput in an ReferenceArrayInput

What happened instead:

AutocompleteArrayInput keeps re-rendering

Steps to reproduce:

Add a disabled AutocompleteArrayInput in a ReferenceArrayInput

Related code: https://stackblitz.com/edit/github-dmhu7h?file=src%2Fposts%2FPostEdit.tsx,package.json

Other information:

Environment

My poor Firefox :fox_face: image

adguernier commented 5 months ago

Reproduced, thanks for this report :pray:

fzaninotto commented 5 months ago

Interesting: I can reproduce with 2 ReferenceArrayInputs

const PostEdit = () => (
  <Edit>
    <SimpleForm defaultValues={{ average_note: 0 }} warnWhenUnsavedChanges>
      <ReferenceArrayInput source="authors" reference="users">
        <AutocompleteArrayInput fullWidth disabled />
      </ReferenceArrayInput>
      <TagReferenceInput reference="tags" source="tags" label="Tags" />
    </SimpleForm>
  </Edit>
);

But not with 1:

const PostEdit = () => (
  <Edit>
    <SimpleForm defaultValues={{ average_note: 0 }} warnWhenUnsavedChanges>
      <ReferenceArrayInput source="authors" reference="users">
        <AutocompleteArrayInput fullWidth disabled />
      </ReferenceArrayInput>
      {/*<TagReferenceInput reference="tags" source="tags" label="Tags" /> */}
    </SimpleForm>
  </Edit>
);

See my stackblitz https://stackblitz.com/edit/github-dmhu7h-ytpyvk?file=src%2Fposts%2FPostEdit.tsx

fzaninotto commented 5 months ago

I confirm the bug is triggered by having 2 ReferenceArrayInput in the same form, one of which at least uses a disabled AutocompleteArrayInput. This is probably a loop in the form state management. The trigger: React-hook-form removes disabled fields from the input state.

fzaninotto commented 5 months ago

No need for ReferenceArrayInput. Two autocompleteInputs are enough.

const PostEdit = () => (
  <Edit>
    <SimpleForm>
        <AutocompleteArrayInput source="authors" disabled choices={[]} />
        <AutocompleteArrayInput source="tag_ids" choices={[]} />
    </SimpleForm>
  </Edit>
);

Click on the second input to trigger the bug

fzaninotto commented 5 months ago

The bug requires react-hook-form >= 7.49.1. It doesn't occur with v4.19.0.

It's probably caused by one of the two following changes:

See https://github.com/react-hook-form/react-hook-form/releases/tag/v7.49.1

fzaninotto commented 5 months ago

The bug occurs here in react-admin:

https://github.com/marmelab/react-admin/blob/717d292192f5d44dc5f10a05f2699f354ad06bae/packages/ra-core/src/form/useApplyInputDefaultValues.ts#L91

Commenting this line removed the bug.