You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React表格中如何实现每行仅选中一个Radio Button?

实现表格每行单选一个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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 01:17:40