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

values prop not honored by useForm #1780

Open
skills-up opened this issue Jan 29, 2024 · 3 comments
Open

values prop not honored by useForm #1780

skills-up opened this issue Jan 29, 2024 · 3 comments
Labels
react Related to the react adapter

Comments

@skills-up
Copy link

skills-up commented Jan 29, 2024

I'm using a generic component for Create/Update forms. The difference between the two is values parameter passed to Update form.

const GenericForm: React.FC<GenericFormProps> = ({
  fields,
  values = null,
  ...
}) => {
  const defaultValues = {};
  for (let key of Object.keys(fields)) {
    defaultValues[key] = getDefaultValueForType(fields[key]);
  }
  const { data, setData, post, put, processing, errors, reset } = useForm(values || defaultValues);
}

Now, this is called in the following manner for the two purposes:
Create Form

<GenericForm fields={formFields}/>

Update Form

<GenericForm fields={formFields} values={currentValues}/>

However, when the form is rendered, the data always contains the defaultValues and never the values. While this is OK for Create Form, it means losing the existing value for Update Form.

@skills-up skills-up added the react Related to the react adapter label Jan 29, 2024
@skills-up
Copy link
Author

Also,

I've tried the following alternative for populating defaultValues object:

  const defaultValues = {};
  for (let key of Object.keys(fields)) {
    defaultValues[key] = values ? values[key] : getDefaultValueForType(fields[key]);
  }

Log shows the defaultValues is updated by the data within values object, but data for form remains the same.

@skills-up
Copy link
Author

Further, if I try to use setDefaults, like:

if (values) {
  setDefaults(values);
}

then it results in Too many rerenders; whereas, wrapping it in a useEffect results in the original behavior mentioned in this issue.

@Hasan-Mir
Copy link

This issue isn’t specific to Inertia; it’s a characteristic of React’s useState.
The useForm hook uses the initial form data passed to it to set up its internal state. This state is only initialized once when the component is first rendered. If you try to update the form data from outside the component by passing different values props, it won’t affect the internal state of the useForm hook after it’s been initialized.

If you want to do so, you need to write a useEffect for it to update the data whenever the props gets a new value:

useEffect(() => {
   setData(values)
}, [values])

However, here you need to use useMemo for the object that's passed to GenericForm as the values prop in the parent component of GenericForm which renders it. Alternatively, you can use JSON.stringify(values) as the dependency for useEffect:

useEffect(() => {
   setData(values)
}, [JSON.stringify(values)])

Another possible solution is to create a key based on the values prop and pass that key to your GenericForm component. This will force React to unmount and remount your component, effectively resetting the useForm hook with the new values:

<GenericForm key={JSON.stringify(currentValues)} fields={formFields} values={currentValues}/>

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

No branches or pull requests

2 participants