Search code examples
javascriptreactjsmaterial-uiformikformik-material-ui

React: Material UI Radio Button Group reset in Formik form not working


formik.resetForm() correctly resets the value, but the Material UI radio button group will not be reset correctly: The last selected radio button stays selected. How to reset the radio button group correctly after submit?

import { useFormik } from "formik";
import {
  Stack,
  Button,
  FormControl,
  FormControlLabel,
  FormGroup,
  FormHelperText,
  FormLabel,
  Radio,
  RadioGroup,
  TextField,
} from "@mui/material";

export default function App() {
  const players = ["player 1", "player 2"];
  const formik = useFormik({
    initialValues: {
      winner: "",
    },
    onSubmit: (values, { resetForm }) => {
      resetForm();
    },
  });
  return (
    <div className="App">
      <h1>Demo Radio Group Reset</h1>
      <h2>
        After pressing Save, the form will be reset, but the reset of the radio
        group does not work.
      </h2>
      <p>value: {formik.values.winner || "<empty>"}</p>
      <form onSubmit={formik.handleSubmit}>
        <Stack>
          <FormControl
            required
            error={formik.touched.winner && Boolean(formik.errors.winner)}
          >
            <FormLabel sx={{ textAlign: "left" }}>Winner</FormLabel>
            <RadioGroup
              row
              name="winner"
              onChange={formik.handleChange}
              onBlur={formik.handleBlur}
            >
              {players.map((player) => (
                <FormControlLabel
                  key={player}
                  value={player}
                  control={<Radio />}
                  label={player}
                />
              ))}
            </RadioGroup>
            <FormHelperText>
              {formik.touched.winner && formik.errors.winner}
            </FormHelperText>
          </FormControl>
          <Button variant="contained" type="submit">
            Save
          </Button>
        </Stack>
      </form>
    </div>
  );
}

See running example at stackblitz


Solution

  • You can set the checked property of the FormControlLabel component to mention that it should display checked only if the formik has a winner value and its same with the player:

    {players.map((player) => (
        <FormControlLabel
            key={player}
            value={player}
            label={player}
            // Check the selected one
            checked={formik.values.winner === player}
            control={<Radio />}
        />
    ))}
    

    I also created a DEMO LINK to review and test it easily

    Hope, it's clear and helpful