I have radio buttons: A, B, and C.
Under button B, there's a select box and I want to make this select box 'required' only when B is selected.
Here's simplified code:
interface ButtonFormType {
notificationType: "A" | "B" | "C";
selectedId?: string;
}
const {
register,
handleSubmit,
getValues,
watch,
formState: { errors },
} = useForm<ButtonFormType>();
.
.
.
return(
<form onSubmit={submit}>
<RadioGroup defaultValue={getValues("buttonType")}>
<VStack>
<Radio {...register("buttonType")} value={"A"}> Button A </Radio>
<Radio {...register("buttonType")} value={"B"}> Button B </Radio>
<FormControl isInvalid={!!errors[`selectedId`]}>
<Select
placeholder={"select"}
{...register("selectedId", {
required:
getValues("buttonType") === "B"
? "please select id"
: false,
})}
>
{idList.map(({ id, title }) => {
return (
<option key={id} value={id}>
{title}
</option>
);
})}
</Select>
</FormControl>
<Radio {...register("buttonType")} value={"C"}> Button C </Radio>
</VStack>
</RadioGroup>
<HStack marginY="40px" spacing={4}>
<Button type="submit"> Submit </Button>
</HStack>
</form>
)
when I choose button B (not select anything from select box) and hit the submit button, it does not give me any error.
If I hit the submit button again, it gives error message.
I inspected and found out that getValues("buttonType")
is not updated as soon as I change buttonType.
It's updated once I hit the submit button. why?
I could solve this issue by changing getValues
to watch
like this
required:
watch("buttonType") === "B"
? "please select id"
: false,
but still can't understand why getValues does not work. Does anybody know?
You can refer to this description.
The difference between watch and getValues is that getValues will not trigger re-renders or subscribe to input changes.
So getValues
doesn't know your real time change, but watch
does.