Search code examples
reactjsmaterial-uireact-hook-form

Material UI switch inputs not updating on form reset


I'm using react-hook-form to build out my form, it is a great tool. However, I can't seem to get the <Switch /> elements to slide (false/true) based on the return values from redux. When I click "reset" on my form, all of my inputs reset. My Switch controls do not reset, they remain stuck on their last value regardless of it being possibly reset. Any thoughts on how to address this?

my Switch

<FormControlLabel
  control={
    <Switch
      size="medium"
      name="familyFriendly"
      defaultChecked={formState.content.isFamilySafe}
      {...register('content.isFamilySafe')}
    />
  }
  label="Family Friendly"
/>

reset button

   <button
        type="button"
        onClick={() => {
          reset(formState, {
            keepErrors: true,
            keepDirty: true,
            keepIsSubmitted: false,
            keepTouched: false,
            keepIsValid: false,
            keepSubmitCount: false,
          });
        }}
      >
        reset
      </button>

useForm hook

  const formState = useSelector(selectDynamicForm);
  const {
    register,
    control,
    handleSubmit,
    reset,
    formState: { errors },
  } = useForm<IFormInput>({});

Solution

  • MUI's <Switch /> component has a slightly different interface for the actual value using checked instead of value. RHF's register returns a value property which you spread on the <Switch /> component, so checked is never linked between RHF and the <Switch /> component.

    So you should use RHF's <Controller /> component to control this external controlled component. Check here for more information.

    <FormControlLabel
        control={
          <Controller
            control={control}
            name="content.isFamilySafe"
            render={({ field: { value, ...field } }) => (
              <Switch {...field} checked={!!value} size="medium" />
            )}
          />
        }
        label="Family Friendly"
    />
    

    You also need to set the defaultValue for your input via useForm as this is required for reset to work properly. From the docs:

    If your form will invoke reset with default values, you will need to call useForm with defaultValues instead of setting the defaultValue on individual fields.

    Edit React Hook Form - MUI Switch