Upgrading to v2
Update your dependencies
Update @formiz/core and @formiz/validations packages to 2.x.x
yarn upgrade @formiz/core @formiz/validationsUpdate React react and react-dom (also @type/react and @type/react-dom if your are using Typescript).
yarn upgrade react@latest react-dom@latest
yarn upgrade -D @types/react@latest @types/react-dom@latestUpgrade <Formiz />
π <Formiz> component doesn't accepts form actions definitions anymore. Now the only props that <Formiz /> accepts are connect and autoForm, and connect is required.
Others props has to be past to useForm now.
Upgrade useForm
New usage
useForm has been split into 3 different hooks: useForm, useFormContext and useFormFields.
π useForm is still used for creating a new form like before. However, there is two changes :
- Now contains form actions definitions (like
onSubmitfor example). - The
subscribeproperty is gone, and the hook now only returns the form's state and actions.
β¨ useFormContext is used to access the form's state and actions in a sub component. It will not create a new form so you can't connect it to a <Formiz> component.
β¨ useFormFields is used to access fields states (not only values).
- Use it at top level with the
connectoption (useFormFields({ connect: form })) or in a sub component (without theconnectoption). - Use a selector to get only the values (
useFormFields({ selector: (field) => field.value })). - Get only some fields with the
fieldsoptions (useFormFields({ fields: ['myField']))
const MyForm = () => {
const form = useForm();
console.log({ values: form.values }) // β Doesn't work anymore
const handleSubmit = (values) => {
console.log({ values })
}
// β Formiz doesn't accept form actions anymore
return <Formiz connect={form} onSubmit={handleSubmit}>
<MyChildren />
<MyField name="myField" />
<MyField name="myOtherField" />
</Formiz>;
};
const MyChildren = () => {
const form = useForm({ subscribe: { fields: ['myField'] } }); // β Doesn't get the form anymore
console.log({ form.values }) // β Doesn't work anymore
return <>
{/* your code here */}
</>;
};const MyForm = () => {
const form = useForm({ onSubmit: (values) => { // β
Form values passed in useForm
console.log({ values })
}});
const values = useFormFields({
connect: form,
selector: (field) => field.value, // β
Get only the values
});
console.log({ values }); // β
{ myField: 'my field value', myOtherField: 'my field value' }
return (
<Formiz connect={form}>
<MyChildren />
<MyField name="myField" />
<MyField name="myOtherField" />
</Formiz>
);
};
const MyChildren = () => {
const form = useFormContext(); // β
Works
const values = useFormFields({
fields: ["myField"],
selector: (field) => field.value,
}); // β
Works
console.log({ values }); // β
{ myField: 'my field value' }
return <>{/* your code here */}</>;
};Form actions updates
π setFieldsValues renamed to setValues
- π
keepPristineoption now defaults to false. - β
keepUnmountedwas removed.setValueswill now always behave as ifkeepUnmountedwastrue.
π invalidateFields renamed to setErrors
π getFieldStepName renamed to getStepByFieldName
π nextStep renamed to goToNextStep
π prevStep renamed to goToPreviousStep
Upgrade useField
Validations API changes
π rule renamed to handler
π Validations don't run on falsy values by default anymore
- You don't need to check on every validation that you have a value (
null,undefined,''orfalse) if your field is not required - If you want to check falsy values (like Formiz v1), just pass the
checkFalsyoption totrue. - Now validations are now executed against formatted value.
<MyField
name="myField"
validations={[
{
rule: (value) => !value || value === "something", // π« `!value ||` useless with v2
message: 'Value must be "something"',
},
]}
/>
<MyField
name="myOtherField"
validations={[
{
rule: (value) => value === "something", // π« Will not be trigger on falsy value with v2
message: 'Value is required and must be "something"',
},
]}
/><MyField
name="myField"
validations={[
{
handler: (value) => value === "something", // β
Only triggered if required pass
message: 'Value must be "something"',
},
]}
/>
<MyField
name="myOtherField"
validations={[
{
handler: (value) => value === "something",
message: 'Value is required and must be "something"',
checkFalsy: true, // β
Opt-in to check also falsy value
},
]}
/>Field props renamed
π onChange renamed to onValueChange
π debounce renamed to debounceValidationsAsync
This will only debounce the async validations and not the value anymore. This prevents a lot of weird behaviors that were existing in v1. Now the value is handled by React v18 to optimize renders.
π asyncValidations renamed to validationsAsync
useField params renamed
π validating.start() renamed to externalProcessing.start() and π validating.end() renamed to externalProcessing.end()
Types changes
You can now type the value of useField by passing a type to the FieldProps type. Also the otherProps will now be typed correctly π.
// β
Pass the value type here ------------------------- π
type MyFieldProps<FormattedValue = string> = FieldProps<string, FormattedValue>
const MyField = <FormattedValue = string,>(props: MyFieldProps<FormattedValue>) => {
const { value, setValue, otherProps } = useField(props);
//...
};The formatted value is by default the same that the value, but you can dynamicly override it.
<MyField<boolean>
// ------- π I need to specify that my formatted value
// Because I format my value to another type
// ----------------- π
formatValue={v => !!v}
/>