The Ultimate MUI RadioGroup Example (Five Best Features!)

The MUI RadioGroup is a specialized component for wrapping radio buttons and controlling alignment. As we will see later, it renders the same as a FormGroup except with role="radiogroup".

Here’s the example we will build in this tutorial:

MUI RadioGroup Example
MUI RadioGroup Example

This RadioGroup has an onChange handler and can be given error and disabled states through its parent FormControl. My RadioGroup has a default value and is horizontally aligning its children Radio buttons.

MUI RadioGroup Horizontal

RadioGroup is similar to FormGroup. The two primary features of RadioGroup are layout control and semantic markup.

The RadioGroup has display: flex applied by default because it has class MuiFormGroup-root applied. There is no MuiRadioGroup-root class.

The RadioGroup is used so often for layout that it has a built-in prop named row for determining flex direction:

<RadioGroup row />

The row prop sets flex direction to row, while the default flex direction is column.

We’ll discuss the semantic meaning in the Styling section.

MUI RadioGroup onChange

RadioGroup detects changes in child radio buttons and fires a change event. Use the onChange prop to handle the change event:

const disabledText = "DISABLED";
const errorText = "ERROR";
const clearText = "NONE";

export default function RadioGroupExample() {
  const [state, setState] = useState(clearText);
  const handleRadioChange = (event: React.ChangeEvent<HTMLInputElement>, value: string) => {
    setState(value);
  }
  return (
    <RadioGroup onChange={handleRadioChange }>
      <FormControlLabel
        value={errorText}
        control={<Radio />}
        label="Set ERROR"
    />
    <FormControlLabel
      value={disabledText}
      control={<Radio />}
      label="Set DISABLED"
    />
    <FormControlLabel
      value={clearText}
      control={<Radio />}
      label="Set NONE"
    />
    </RadioGroup>
  )
}

RadioGroup onChange passes an event and value by default. The value comes from the child Radio that was selected.

In my demo I created three constants for state and use these as the values on the Radios. In the handler I simply set React useState hook with the Radio value.

RadioGroup onChange is similar to the MUI Switch onChange handler.

MUI RadioGroup Default Value

The default value can quickly be set using the defaultValue prop.

<RadioGroup defaultValue={clearText}/>

Make sure you don’t assign a state value to the defaultValue or you may see warnings in the DOM when the state changes. A default value should not change.

The default value trickles down to children Radios and auto-selects the Radio with a matching value.

In my demo the third Radio (“Set NONE”) is selected by default.

MUI RadioGroup default value
MUI RadioGroup default value

MUI RadioGroup Error

Interestingly, the Material UI RadioGroup does not have an error prop. When the parent FormControl has an error state, the class Mui-error is applied to the RadioGroup but there is no visual difference.

MUI RadioGroup Error
MUI RadioGroup Error

In my example, the FormLabel and FormHelperText change color as a visual indication that the FormControl has an error state. However, those are outside of the RadioGroup. The RadioGroup itself shows no change, but if desired we could use the auto-applied Mui-error class to show some error styling.

MUI RadioGroup Disabled

The Material UI RadioGroup does not have a disabled prop, just like it does not have error. However, when the parent FormControl’s disabled prop is true, the RadioGroup doesn’t even get a class of Mui-disabled.

The children FormControlLabels do detect the parent FormControl’s disabled state and auto-apply a Mui-disabled class.

MUI RadioGroup Disabled DOM
MUI RadioGroup Disabled DOM

This changes the visual presentation of the child FormControlLabels and Radios:

MUI RadioGroup Disabled Example
MUI RadioGroup Disabled Example

The DOM differences between error and disabled are surprising to me.

How to Style the MUI RadioGroup

Below is how the RadioGroup renders in the DOM. There’s no indication that it is a RadioGroup instead of a FormGroup, except for the role and aria-labelledby attributes.

MUI RadioGroup DOM
MUI RadioGroup DOM

The RadioGroup is also a simple one-element component. This makes styling easy. However, we may want to style child elements, and for that we need nested selectors. Here’s the styling for this tutorial:

<RadioGroup
  sx={{
    boxShadow: 3,
    backgroundColor: "rgba(0,0,0,0.1)",
    "& .MuiRadio-root": { color: "green" },
    "& .MuiRadio-root.Mui-checked": { color: "orange" },
  }}
/>

I applied a box shadow and background color on the RadioGroup. I then targeted the child Radio elements’ root class with a selector and set them to green. Finally, I set the selected radio to orange. MUI applies class Mui-checked to make selectors easy on the checked element. Checkboxes receive this class as well.

Resources

Here are the MUI RadioGroup API docs.

Full code for this tutorial:

import { useCallback, useState } from "react";
import Radio from "@mui/material/Radio";
import RadioGroup from "@mui/material/RadioGroup";
import FormControlLabel from "@mui/material/FormControlLabel";
import FormControl from "@mui/material/FormControl";
import FormHelperText from "@mui/material/FormHelperText";
import FormLabel from "@mui/material/FormLabel";

const disabledText = "DISABLED";
const errorText = "ERROR";
const clearText = "NONE";

export default function RadioGroupExample() {
  const [state, setState] = useState(clearText);
  const handleRadioChange = (
    event: React.ChangeEvent<HTMLInputElement>,
    value: string
  ) => {
    setState(value);
  };
  return (
    <>
      <form>
        <FormControl
          sx={{ m: 2 }}
          variant="filled"
          disabled={state === disabledText}
          error={state === errorText}
        >
          <FormLabel id="radios">Set RadioGroup State</FormLabel>
          <RadioGroup
            aria-labelledby="radios"
            name="quiz"
            row
            onChange={handleRadioChange}
            defaultValue={clearText}
            sx={{
              boxShadow: 3,
              backgroundColor: "rgba(0,0,0,0.1)",
              "& .MuiRadio-root": { color: "green" },
              "& .MuiRadio-root.Mui-checked": { color: "orange" },
            }}
          >
            <FormControlLabel
              value={errorText}
              control={<Radio />}
              label="Set ERROR"
            />
            <FormControlLabel
              value={disabledText}
              control={<Radio />}
              label="Set DISABLED"
            />
            <FormControlLabel
              value={clearText}
              control={<Radio />}
              label="Set NONE"
            />
          </RadioGroup>
          <FormHelperText>{state}</FormHelperText>
        </FormControl>
      </form>
    </>
  );
}
Share this post:

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.