Piplup
@piplup/rhf-adaptersmui-materialHooks

useMuiRadioGroupAdapter

Returns props that connect an MUI RadioGroup to React Hook Form, with null for no selection and transforms for non-string values.

useMuiRadioGroupAdapter connects an MUI RadioGroup to a React Hook Form field and returns props you spread onto the group. The Radio children stay plain MUI radios. It's what MuiRadioGroupElement uses internally.

Use the element for a simple list of options. Reach for the hook when the group, its label and its error message should be one reusable component, or when the stored value isn't a string, like the boolean in the example below. For radios that aren't inside a RadioGroup, see useMuiRadioAdapter.

Import

import { useMuiRadioGroupAdapter } from "@piplup/rhf-adapters/mui-material";

Usage

A yes/no question stored as true or false, starting as null. The transform converts between the booleans in the form and the "true"/"false" strings the radios use. Submit without answering to see the error.

"use client";import FormControl from "@mui/material/FormControl";import FormControlLabel from "@mui/material/FormControlLabel";import FormHelperText from "@mui/material/FormHelperText";import FormLabel from "@mui/material/FormLabel";import Radio from "@mui/material/Radio";import RadioGroup from "@mui/material/RadioGroup";import Stack from "@mui/material/Stack";import {  MuiButtonElement,  useMuiRadioGroupAdapter,} from "@piplup/rhf-adapters/mui-material";import type * as React from "react";import { type Control, useForm } from "react-hook-form";type FormValues = { giftWrap: boolean | null };// A yes/no question stored as a real boolean. The radios work with the// strings "true" and "false"; the transform converts in both directions.function GiftWrapField({ control }: { control: Control<FormValues> }) {  const { error, helperText, ...adapter } = useMuiRadioGroupAdapter<    string | null,    FormValues,    "giftWrap",    HTMLDivElement  >({    control,    name: "giftWrap",    composeHelperText: true,    // Not `required`: React Hook Form treats `false` as missing.    rules: {      validate: (value) => value !== null || "Choose yes or no",    },    transform: {      input: (value) => (typeof value === "boolean" ? String(value) : null),      output: (_event: React.ChangeEvent<HTMLInputElement>, value: string) =>        value === "true",    },  });  return (    <FormControl error={error}>      <FormLabel id="gift-wrap-label">Gift wrap this order?</FormLabel>      <RadioGroup row aria-labelledby="gift-wrap-label" {...adapter}>        <FormControlLabel value="true" control={<Radio />} label="Yes" />        <FormControlLabel value="false" control={<Radio />} label="No" />      </RadioGroup>      {helperText ? <FormHelperText>{helperText}</FormHelperText> : null}    </FormControl>  );}export default function Page() {  const { control, handleSubmit } = useForm<FormValues>({    defaultValues: { giftWrap: null },  });  return (    <form      noValidate      onSubmit={handleSubmit((values) =>        alert(JSON.stringify(values, null, 2)),      )}    >      <Stack direction="column" spacing={2}>        <GiftWrapField control={control} />        <div>          <MuiButtonElement control={control} type="submit" variant="contained">            Continue          </MuiButtonElement>        </div>      </Stack>    </form>  );}

How it works

One registration for the group. The hook registers the field once and the RadioGroup tells its radios which one is checked. Compare this with useMuiRadioAdapter, where every radio is wired to the field separately.

Empty values. An undefined field value is passed to the group as null, so the group stays controlled with nothing selected. On change, the hook stores the selected radio's value, or null if that value is "" or undefined.

Values are strings. RadioGroup reports the selected radio's value as a string, so by default the field ends up holding strings. To store numbers or booleans, override both directions with transform: input turns the field value into the string the radios use, and output receives (event, value) and returns what to store. Each key you set replaces the default for that direction, so handle undefined and null in your own input.

Inside a FormControl. If you don't pass disabled or required, the hook takes them from the surrounding MUI FormControl.

Errors. RadioGroup doesn't render errors. Put the returned error on a FormControl and render helperText in a FormHelperText. With composeHelperText: true, helperText is the field's error message, falling back to your helperText when there's no error.

What's returned. name, value, onChange, onBlur, ref, disabled, required, error, helperText, className, style and classes. title is not returned.

React Hook Form's required rule treats false as missing. If you store a boolean, required rejects the "No" answer. Use rules.validate to check for null instead, as the demo does.

RadioGroup has no error or helperText props. Remove them from the returned object before spreading, as the demo and the element do.

Props

Prop

Type

Return value

Prop

Type

On this page