Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ArrayInput has different behaviour in dev and in build #9617

Open
PedroPerpetua opened this issue Jan 26, 2024 · 6 comments
Open

ArrayInput has different behaviour in dev and in build #9617

PedroPerpetua opened this issue Jan 26, 2024 · 6 comments

Comments

@PedroPerpetua
Copy link
Contributor

The ArrayInput component has a breaking different behaviour in the dev environment and when you actually build the project; an empty ArrayInput (that has not been interacted with) will:

  • Return an empty array in dev
  • Return undefined in the build

Note: interacting with it in the build version (adding an entry) but still leaving it empty (removing all entries before submitting) will return an empty array too, as expected.

What you were expecting:

Both environments should behave the same way, preferably returning an empty array in both.

What happened instead:

Inside the build, a not-interacted ArrayInput returns undefined.

Steps to reproduce:

  • Have a Create Page with an ArrayInput
  • Create a new record with said page, without adding any entries to the ArrayInput
  • Submit the creation

Related code:

Since this issue requires a build, instead of a sandbox I provide a minimal reproduction example repo: https://github.com/PedroPerpetua/ra-array-input-bug

This was bootstrapped with react-admin, and replaced the dataProvider with a very simple one that will just alert information about the type received from the ArrayInput, alongside a CreatePage that features an ArrayInput.

The dev server can be started with yarn dev and the build created with yarn build, as per usual.

Other information:

Environment

  • React-admin version: 4.16.7 (the minimal repo uses the version included in the bootstrap, but I have verified the issue with this one too)
  • React version: 18.2.0
  • Browser: Chrome
@slax57
Copy link
Contributor

slax57 commented Feb 5, 2024

Nice catch!
I could reproduce with a fresh project created with create-react-admin.

I suspect something linked to React 18 and Strict Mode which is probably enabled in dev mode but not in the production build.

@slax57 slax57 added the bug label Feb 5, 2024
@PedroPerpetua
Copy link
Contributor Author

PedroPerpetua commented Feb 5, 2024

I belive (could be wrong) that the only change Strict Mode makes that actually could change behaviour is that it will run useEffect twice for components... maybe there's something that doesn't get initialized correctly the first time, but on the second run it finally does?

Edit: correction - not just useEffect, but all lifecycles. Relevant: https://react.dev/reference/react/StrictMode

@fzaninotto fzaninotto removed the bug label Oct 3, 2024
@fzaninotto
Copy link
Member

I confirm the bug still exists in V5. Reproduction: https://github.com/fzaninotto/ra-array-input-bug

@fzaninotto
Copy link
Member

The production behavior is the correct one: if you don't define a default value, it is set to undefined. The fact that this value becomes an empty array in development is probably due to a race condition between react-hook-form that seems tp set the value to an empty array) and our own useApplyInputDefaultValues (that sets the value to undefined).

In any case, if you need the default value to be an empty array in production, you can always use the defaultValue prop:

-       <ArrayInput source="array_input">
+       <ArrayInput source="array_input" defaultValue={[]}>
          <SimpleFormIterator>
            <TextInput source="text_input" />
          </SimpleFormIterator>
        </ArrayInput>

As there is an easy workaround, we're considering this a low-priority bug.

@fzaninotto
Copy link
Member

I can't replicate with react-hook-form alone (see codesandbox), so it indeed seems to be a react-admin issue.

@fzaninotto
Copy link
Member

fzaninotto commented Nov 8, 2024

React-hook-form sets the value to [] on mount:

https://github.com/react-hook-form/react-hook-form/blob/281f91355e90f3a165cd64ae3bcc9d850617e3ad/src/useFieldArray.ts#L401

https://github.com/react-hook-form/react-hook-form/blob/281f91355e90f3a165cd64ae3bcc9d850617e3ad/src/logic/createFormControl.ts#L202

Note that this default value isn't detected by a useWatch, which registers too late. to see it, I had to use the following component:

export const FormInspector = () => {
    const { getValues } = useFormContext();
    React.useEffect(() => {
        console.log('Form values:', getValues());
    });
    return null;
};

For some reason, react-admin removes this default value shortly after mount.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants