Material UI Checkbox组件结合React-Hook-Form无法返回布尔值问题求助
Hey Andrea, let's break down why your Material UI Checkbox isn't returning true/false correctly, and how to fix it.
The Root Cause
The issue here is that Material UI's Checkbox is a custom component, not a native <input type="checkbox">. React Hook Form's register function is built to work seamlessly with native form elements, but custom components like MUI's Checkbox don't expose the same default event handling or value structure. That's why your native checkbox works, but the MUI one doesn't sync properly with your form state.
Solution 1: Use React Hook Form's Controller (Recommended)
React Hook Form provides the Controller component specifically to handle custom UI components. It acts as a bridge between the component and your form state.
First, make sure you import Controller from react-hook-form:
import { Controller, useForm } from "react-hook-form";
Then update your code like this:
// Initialize your form (adjust based on your existing setup) const { control, watch } = useForm({ defaultValues: { hasPhone: data.hasPhone, phoneNumber: "" } }); // Watch the "hasPhone" value for your conditional rendering const hasPhone = watch("hasPhone"); <FormControlLabel control={ <Controller name="hasPhone" control={control} render={({ field }) => ( <Checkbox {...field} checked={field.value} color="primary" /> )} /> } label="Do you have a phone" /> {hasPhone && ( <Input {...register("phoneNumber")} id="phoneNumber" type="tel" label="Cellulare" name="phoneNumber" /> )}
Why this works:
Controllerhandles syncing the form state with the MUI Checkbox automatically.- The
renderprop gives you access tofield(which includesvalue,onChange, and other necessary props) that you pass to the Checkbox. - Manually setting
checked={field.value}ensures the Checkbox's visual state matches the form's internal state perfectly.
Solution 2: Manual State Sync (No Controller)
If you prefer not to use Controller, you can manually sync the Checkbox state with your form using setValue and watch:
const { register, watch, setValue } = useForm({ defaultValues: { hasPhone: data.hasPhone } }); const hasPhone = watch("hasPhone"); <FormControlLabel control={ <Checkbox checked={hasPhone} onChange={(e) => setValue("hasPhone", e.target.checked)} color="primary" /> } label="Do you have a phone" /> {hasPhone && ( <Input {...register("phoneNumber")} id="phoneNumber" type="tel" label="Cellulare" name="phoneNumber" /> )}
Why this works:
watch("hasPhone")keeps track of the current form value for the checkbox.- We bind that value to the Checkbox's
checkedprop to keep the UI in sync with the form state. - On
onChange, we usesetValueto update the form state with the new checked status.
Final Notes
Both methods will fix your conditional rendering issue. The Controller approach is the official recommended way because it abstracts away manual state management and integrates more cleanly with React Hook Form's ecosystem.
内容的提问来源于stack exchange,提问作者Andrea

