AuthorProxy
AuthorProxy

Reputation: 8047

React hook form method - setValue - doesn't work

I have some clearable select, and I want to reset the applets field in state to an empty array.

const defaultFormValues = { device: { ...initialDevice }, applets: [] };
  const { control, getValues, setValue, reset, handleSubmit } = useForm<CreateDeviceFormData>({
    mode: "all",
    reValidateMode: "onChange",
    defaultValues: defaultFormValues,
    resolver: yupResolver(validationSchema),
  });

  const onChangeHandler = React.useCallback(
    (value: Experience | null) => {
      if (value) {
        setValue("applets", getApplets(value));
      } else {
        setValue("applets", []);
        // reset(defaultFormValues);
      }

      setValue("device.experience_id", value ? value.id : undefined);
    },
    [templateSelector, setValue],
  );

  console.log("current data", getValues(), control);
  return (
    <>
      <SomeAutocompleteComponent control={control} onChange={onChangeHandler} />
      <SelectAppletsComponent control={control} />
    </>
  );


export const SelectAppletsComponent = ({ control, onChange }) => {
  const applets = useWatch({ control, name: "applets" }) as Applet[];
  const device = useWatch({ control, name: "device" }) as Device;

  if (!applets.length) {
    return null;
  }

  return (
    <SpanWrapper className="p-col-8">
      {applets.map((applet) => (
        <LabelRadio
          key={applet.id}
          inputId={applet.applet_type}
          value={applet.applet_type}
          label={applet.name}
          checked={device.applet_type === applet.applet_type}
          onChange={onChange}
        />
      ))}
    </SpanWrapper>
  );
};

the problem is that clearing the selection on UI with setValue("applets", []); not working for some reason, and I don't understand why, and how to do it without reset method, which resets the whole state, not just single property as I understand

Upvotes: 3

Views: 13193

Answers (2)

AuthorProxy
AuthorProxy

Reputation: 8047

You should always register fields if you want to use them as RHF's form state.

  React.useEffect(() => {
    register("applets");
  }, [register]);

This fixes an issue.

Update: Also a new method resetField is available

Upvotes: 6

Tan-Aki
Tan-Aki

Reputation: 307

Just to follow up on this, it is indeed the right solution provided by AuthorProxy.

Using defaultValues doesn't register the fields (it seems that they are still added to the formData on submit, but since they are not registered, any user triggered changes to these fields won't reflect on the formData).

You have to register every field you want the user to be able to interact with. We usually register fields via inputs in the JSX, but we also need to register the array since there is no input for it in the JSX.

As per shown by the author of the react hook form library.

https://github.com/react-hook-form/react-hook-form/discussions/3160

And sandbox

https://codesandbox.io/s/inspiring-wood-4z0n0?file=/src/App.tsx

Upvotes: 2

Related Questions