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}
/>