React表格中如何实现每行仅选中一个Radio Button?
要实现每行仅能选中一个Radio Button,核心是让同一行的两个Radio属于同一分组,同时结合Formik管理状态。以下是具体修改步骤:
1. 调整Formik状态结构
将每行的两个Radio状态合并为一个字段(比如selectedOption),值用'radio1'或'radio2'这类标识区分选项,而非分开的布尔值。这种结构更贴合单选逻辑,也简化状态管理。
2. 修改CustomTableRow组件
更新FastField配置,让同一行的两个Radio共享相同的name,通过value区分选项,并绑定checked属性同步选中状态:
import { TableCell, TableRow, Radio } from "@mui/material"; import { FastField } from "formik"; import CustomTextField from "./CustomTextField"; const CustomTableRow = ({ row, index }) => { return ( <TableRow key={row.id} sx={{ "&:last-child td, &:last-child th": { border: 0 }, }} > <TableCell component="th" scope="row"> <FastField name={`rows.${index}.attribute`} component={CustomTextField} fullWidth size="small" /> </TableCell> <TableCell> <FastField name={`rows.${index}.selectedOption`} component={CustomTextField} type="radio" value="radio1" checked={(form) => form.values.rows[index]?.selectedOption === "radio1"} fullWidth /> </TableCell> <TableCell> <FastField name={`rows.${index}.selectedOption`} component={CustomTextField} type="radio" value="radio2" checked={(form) => form.values.rows[index]?.selectedOption === "radio2"} fullWidth /> </TableCell> </TableRow> ); }; CustomTableRow.displayName = "CustomTableRow"; export default CustomTableRow;
3. 确保CustomTextField支持Radio类型
如果你的CustomTextField是基于MUI TextField封装的,需要确认它能正确处理Radio输入的type、value、checked属性。如果适配困难,也可以直接封装专门的RadioField组件配合Formik:
import { TableCell, TableRow, Radio, FormControlLabel } from "@mui/material"; import { FastField, useField } from "formik"; import CustomTextField from "./CustomTextField"; const RadioField = ({ name, value, label }) => { const [field] = useField(name); return ( <FormControlLabel control={ <Radio checked={field.value === value} onChange={(e) => field.onChange(e)} value={value} /> } label={label} /> ); }; const CustomTableRow = ({ row, index }) => { return ( <TableRow key={row.id} sx={{ "&:last-child td, &:last-child th": { border: 0 }, }} > <TableCell component="th" scope="row"> <FastField name={`rows.${index}.attribute`} component={CustomTextField} fullWidth size="small" /> </TableCell> <TableCell> <RadioField name={`rows.${index}.selectedOption`} value="radio1" label="选项1" /> </TableCell> <TableCell> <RadioField name={`rows.${index}.selectedOption`} value="radio2" label="选项2" /> </TableCell> </TableRow> ); }; CustomTableRow.displayName = "CustomTableRow"; export default CustomTableRow;
关键说明
- 同一分组:同一行的Radio必须使用相同的
name属性,浏览器会自动处理互斥选中逻辑。 - 状态绑定:通过
checked属性判断当前选项是否与Formik状态值匹配,确保选中状态同步。 - 组件适配:若自定义文本组件不支持Radio,封装专门的RadioField组件会更灵活。
内容的提问来源于stack exchange,提问作者Joseph
相关产品推荐
相关产品推荐

