Upgrading to v2
Update your dependencies
Update @formiz/core
and @formiz/validations
packages to 2.x.x
yarn upgrade @formiz/core @formiz/validations
Update 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@latest
Upgrade <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
onSubmit
for example). - The
subscribe
property 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
connect
option (useFormFields({ connect: form })
) or in a sub component (without theconnect
option). - Use a selector to get only the values (
useFormFields({ selector: (field) => field.value })
). - Get only some fields with the
fields
options (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
- π
keepPristine
option now defaults to false. - β
keepUnmounted
was removed.setValues
will now always behave as ifkeepUnmounted
wastrue
.
π 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
checkFalsy
option 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}
/>