Trying to use RadioGroup from Material UI wrapped with react-hook-form Controller, always getting the selected value null, here is my code, I wonder what I am missing?
import * as React from "react";
import {
FormControl,
FormControlLabel,
FormHelperText,
Radio,
RadioGroup
} from "@mui/material";
import { useState } from "react";
import { useFormContext, Controller } from "react-hook-form";
interface IOptionTypes {
id: string;
label: string;
value: string;
desc?: string;
}
interface IFormElementTypes {
name: string;
options: IOptionTypes[];
}
export default function RadioFieldElement({
name,
options
}: IFormElementTypes) {
const {
control,
register,
formState: { errors }
} = useFormContext();
return (
<Controller
name={name}
defaultValue=""
control={control}
render={({ field }) => (
<FormControl fullWidth>
<RadioGroup
{...field}
{...register(name)}
row
onChange={(event, value) => field.onChange(value)}
value={field.value}
>
{options.map((option) => (
<FormControlLabel
key={option.id}
value={option.value}
control={<Radio />}
label={option.label}
/>
))}
</RadioGroup>
<FormHelperText>{String(errors[name]?.message ?? "")}</FormHelperText>
</FormControl>
)}
/>
);
}
Here is the live code.
Just simply select any value from list and press submit in console you will see the value is null always.
Thanks for help.
Trying to use RadioGroup from Material UI wrapped with react-hook-form Controller, always getting the selected value null, here is my code, I wonder what I am missing?
import * as React from "react";
import {
FormControl,
FormControlLabel,
FormHelperText,
Radio,
RadioGroup
} from "@mui/material";
import { useState } from "react";
import { useFormContext, Controller } from "react-hook-form";
interface IOptionTypes {
id: string;
label: string;
value: string;
desc?: string;
}
interface IFormElementTypes {
name: string;
options: IOptionTypes[];
}
export default function RadioFieldElement({
name,
options
}: IFormElementTypes) {
const {
control,
register,
formState: { errors }
} = useFormContext();
return (
<Controller
name={name}
defaultValue=""
control={control}
render={({ field }) => (
<FormControl fullWidth>
<RadioGroup
{...field}
{...register(name)}
row
onChange={(event, value) => field.onChange(value)}
value={field.value}
>
{options.map((option) => (
<FormControlLabel
key={option.id}
value={option.value}
control={<Radio />}
label={option.label}
/>
))}
</RadioGroup>
<FormHelperText>{String(errors[name]?.message ?? "")}</FormHelperText>
</FormControl>
)}
/>
);
}
Here is the live code.
Just simply select any value from list and press submit in console you will see the value is null always.
Thanks for help.
Share Improve this question asked Aug 12, 2022 at 14:43 iphoniciphonic 12.7k7 gold badges66 silver badges111 bronze badges3 Answers
Reset to default 5In your RadioFieldElement.tsx
you don't need to put {...register(name)}
on your RadioGroup
. Simply remove that and everything will work as expected:
<RadioGroup
{...field}
// remove this line ---> {...register(name)}
row
onChange={(event, value) => field.onChange(value)}
value={field.value}
>
Here's a full codesandbox example:
RadioFieldElement.tsx
import * as React from "react";
import {
FormControl,
FormControlLabel,
FormHelperText,
Radio,
RadioGroup
} from "@mui/material";
import { useState } from "react";
import { useForm, Controller } from "react-hook-form"; // use useForm
interface IOptionTypes {
id: string;
label: string;
value: string;
desc?: string;
}
interface IFormElementTypes {
name: string;
options: IOptionTypes[];
}
export default function RadioFieldElement({
name,
options
}: IFormElementTypes) {
const {
control,
register,
formState: { errors }
} = useForm();
/* const [theValue, setTheValue] = useState(control._defaultValues[name]);
const handleChange = (event) => {
console.log(event.target.value);
setTheValue(event.target.value);
}; */
return (
<Controller
name={name}
defaultValue=""
control={control}
render={({ field }) => (
<FormControl fullWidth>
<RadioGroup
{...field}
{...register(name)}
row
onChange={(event, value) => field.onChange(value)}
value={field.value}
>
{options.map((option) => (
<FormControlLabel
key={option.id}
value={option.value}
control={<Radio />}
label={option.label}
/>
))}
</RadioGroup>
<FormHelperText>{String(errors[name]?.message ?? "")}</FormHelperText>
</FormControl>
)}
/>
);
}
you can simply use mui-react-form-plus
as it is already tested and ready to use for production.
import { HookRadioButton, useHookForm } from 'mui-react-hook-form-plus'
const { registerState } = useHookForm({
defaultValues: {
breverage: 'wine',
isAdmin: true,
},
});
<HookRadioButton
{...registerState('breverage')}
label='Breverage'
fields={[
{ label: 'Coke', value: 'coke' },
{ label: 'Wine', value: 'wine' },
]}
/>
Form more look into:
https://mui-react-hook-form-plus.vercel.app/?path=/docs/hookradiobutton--hookradiobutton