Reputation: 4414
I'm using React-Admin and have a SimpleForm where I want to trigger some generic action any time any of form fields are changed, including a ReferenceInput selection field.
I'm upgrading from React-Admin version 2.9 to 4.x. In the former version I had an onChange control on a SimpleForm and it triggered when any form field was changed, including ReferenceInput fields. In the new version, changing the ReferenceInput dropdown selection no longer triggers the onChange event.
Why is that? And is there some way to get it working again?
...
import {
Create, SimpleForm, TextInput, ReferenceInput, SelectInput
} from 'react-admin';
const doSomething = () => {
// something
};
const ItemCreate = ({ dataProvider, ...props }) => (
<>
<Create title="Create Class" {...props}>
<SimpleForm onChange={doSomething}>
<TextInput source="name" label="Name"/>
<!-- no longer triggers the onChange event (doSomething) -->
<ReferenceInput label="Item" source="item" reference="items">
<SelectInput optionText={(choice) => `${choice.itemName}`} />
</ReferenceInput>
</SimpleForm>
</Create>
</>
Upvotes: 1
Views: 1002
Reputation: 4414
I resolved this using react-hook-form's useFormContext()
, as suggested by @MaxAlex.
I was able to avoid using a pseudo-component. I basically did the following:
onChange
, as it no longer seems to work with React-Admin's ReferenceInputSimpleForm
(when I put useFormContext()
directly into the component that contains SimpleForm it returns null)useEffect
in that separate input component, use useFormContext
, and/or other react-hook-form functionality (e.g., dirtyFields or useWatch) to monitor form field changes and take action based on thatExample:
...
import {
Create, SimpleForm, TextInput, ReferenceInput, SelectInput
} from 'react-admin';
import { useFormContext } from 'react-hook-form';
const MyInput = () => {
const formContext = useFormContext();
useEffect(() => {
const { dirtyFields } = formContext.formState;
// if the user changes fieldA, modify fieldB
if (
Object.keys(dirtyFields).includes('fieldA')
) {
formContext.setValue('fieldB', 1);
}
});
return (
<ReferenceInput label="Form Field B" source="fieldB" reference="items">
<SelectInput optionText={(choice) => `${choice.itemName}`} />
</ReferenceInput>
);
};
...
const ItemCreate = () => {
return (
<Create>
<SimpleForm>
// other form fields, including fieldA
<MyInput />
</SimpleForm>
</Create>
);
};
...
I've found that, in addition to addressing the issue of onChange
no longer working on my ReferenceInput
field, react-hook-form seems to provide more granular control than onChange
did.
Upvotes: 0
Reputation: 709
You can use the validate prop instead of onChange in the SimpleForm
.
And please, read the Form validation section in the docs, this should help you as well.
Upvotes: 0
Reputation: 3319
Somewhere inside the form you can call:
import { useFormContext } from 'react-hook-form'
...
const { watch } = useFormContext()
watch((data, { name, type }) => console.log(data, name, type))
https://react-hook-form.com/api/useformcontext
https://react-hook-form.com/api/useform/watch
Upvotes: 1