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

React.js中动态存储复选框状态并按指定格式提交API

问题根源

你当前所有权限组(section)共享同一个checkedList状态,导致选中某操作(如Add)时,所有section里的同名复选框会同步选中——因为它们绑定的是同一个数组。要解决这个问题,必须按每个section单独存储选中状态。


分步解决方案

1. 调整父组件状态结构

把单一的checkedList数组改成对象,用section名称作为key,对应的值是该section下选中的权限数组:

// 替换父组件中原有的checkedList状态
const [sectionCheckedLists, setSectionCheckedLists] = useState<Record<string, CheckboxValueType[]>>({});

// 组件挂载时,根据API返回的permissionList初始化每个section的默认选中值
useEffect(() => {
  if (permissionList.length > 0) {
    const initialState: Record<string, CheckboxValueType[]> = {};
    permissionList.forEach(item => {
      // 这里沿用你原来的默认选中值,也可以根据需求改成空数组
      initialState[item.section] = ["Add", "Update", "Delete", "View"];
    });
    setSectionCheckedLists(initialState);
  }
}, [permissionList]);

2. 修改父组件的选中状态处理函数

新增带section参数的处理函数,只更新对应section的选中状态:

// 替换父组件中原有的onChange函数
const handleSectionCheckChange = (section: string, list: CheckboxValueType[]) => {
  setSectionCheckedLists(prev => ({
    ...prev,
    [section]: list
  }));
};

3. 更新CheckBoxItem子组件

让子组件接收当前section的专属参数,调整全选逻辑基于当前section的选项:

// 重新定义子组件的Props
interface CheckBoxItemProps {
  section: string; // 当前权限组名称
  checkedList: CheckboxValueType[]; // 当前section的选中列表
  onSectionChange: (section: string, list: CheckboxValueType[]) => void; // 带section的更新函数
  permissionTitle: string;
  isGameOption?: boolean;
  options: CheckboxValueType[]; // 当前section的权限选项(从父组件传入)
}

const CheckBoxItem: React.FC<CheckBoxItemProps> = (props) => {
  const { section, checkedList, onSectionChange, options } = props;

  // 全选/半选逻辑仅针对当前section的选项
  const checkAll = options.length === checkedList.length;
  const indeterminate = checkedList.length > 0 && checkedList.length < options.length;

  const onCheckAllChange = (event: CheckboxChangeEvent) => {
    onSectionChange(section, event.target.checked ? options : []);
  };

  const handleChange = (list: CheckboxValueType[]) => {
    onSectionChange(section, list);
  };

  return (
    <>
      <div className="role-subject-title">
        <h3>{props.permissionTitle}</h3>
      </div>
      <div className="checkbox-design">
        <CheckboxGroup
          options={options}
          value={checkedList}
          onChange={handleChange}
          className="checkbox-style"
        />

        <Checkbox
          indeterminate={indeterminate}
          onChange={onCheckAllChange}
          checked={checkAll}
          className="checkbox-style-all"
        >
          <span style={{ color: "white", fontSize: "20px" }}>
            {APP_CHECKBOX_ROUTE.CHECK_ALL}
          </span>
        </Checkbox>
      </div>
    </>
  );
};

4. 父组件渲染时传递正确参数

遍历permissionList时,给每个CheckBoxItem传入对应section的专属数据:

{permissionList.map((item) => (
  <Collapsible title={item.section} isFirst={item === permissionList[0]} key={item.section}>
    <CheckBoxItem
      section={item.section}
      checkedList={sectionCheckedLists[item.section] || []}
      onSectionChange={handleSectionCheckChange}
      permissionTitle=""
      options={item.name}
      isGameOption={/* 根据你的业务逻辑传true/false,比如判断section是否属于游戏模块 */}
    />
  </Collapsible>
))}

5. 提交时转换为API要求的格式

点击保存按钮时,把状态结构转换成API需要的格式:

const handleSave = () => {
  const submitData = {
    name: gameName || "",
    permissions: permissionList.map(item => ({
      section: item.section,
      name: sectionCheckedLists[item.section] || []
    }))
  };
  // 调用接口发送数据
  dispatch(addRole(submitData));
};

// 给按钮绑定点击事件
<Button htmlType="submit" className="login-button" onClick={handleSave}>
  Save
</Button>

内容的提问来源于stack exchange,提问作者Shiva Giri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 02:59:52