I have input radio in React Hook Form and I try to use it as real boolean, instead of string.
I know that RHF have valueAsNumber to convert it as number. I thought that setValueAs was a generic way to allow any conversion but I can't make it work.
Code Sanbox
const schema = z.object({
  name: z.string().min(4, { message: "4 caractères minimum pour le name" }),
  developer: z.boolean() // A real boolean is expected here
});
export default function App() {
  const {
    register,
    handleSubmit,
    watch,
    formState: { errors }
  } = useForm({
    resolver: zodResolver(schema),
    defaultValues: {
      name: "John",
      developer: false // default as boolean
    }
  });
  return (
    <form onSubmit={handleSubmit(onSubmit)} noValidate>
      <input type="text" placeholder="Name" {...register("name")} />
      <p>
        Is developer ? 
        <label>
          Oui
          <input
            {...register("developer", {
              setValueAs: (val) => true // Try to make it as a real boolean but doesn't work
            })}
            type="radio"
            value={true}
          />
        </label>
        <label>
          Non
          <input
            {...register("developer", {
              setValueAs: (val) => false
            })}
            type="radio"
            value={false}
          />
        </label>
      </p>
      <input type="submit" />
    </form>
  );
}
Any idea?
I find out how to get a boolean from a radio input in RHF.
The solution with setValueAs, as I tried before, only works for text input (like type="text" or type="number"). For radio button, even if the value is a string, it doesn't work.
So it can be solved by using a Controller component.
Code sandbox
function MyBooleanInput({ control, name }) {
  return (
    <Controller
      control={control}
      name={name}
      render={({ field: { onChange, onBlur, value, ref } }) => (
        <>
          <label>
            Oui
            <input
              type="radio"
              onBlur={onBlur} // notify when input is touched
              onChange={() => onChange(true)} // send value to hook form
              checked={value === true}
              inputRef={ref}
            />
          </label>
          <label>
            Non
            <input
              type="radio"
              onBlur={onBlur} // notify when input is touched
              onChange={() => onChange(false)} // send value to hook form
              checked={value === false}
              inputRef={ref}
            />
          </label>
        </>
      )}
    />
  );
}
This way, values are real booleans and zod doesn't throw an error.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With