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

React动态表单单选限制及主存储桶已移动项删除问题

问题修复方案

核心问题分析与解决

1. 每个表单只能单选Radio按钮

原代码中所有Radio.Group共享同一个数组value1,导致无法单独控制每个表单的选中状态,出现多选项可同时选中的问题。

  • 把value1从数组改为对象,键为表单id,值为对应选中的选项值,实现每个表单独立管理选中状态。
  • 修改onChange1方法,针对当前表单id更新选中值,而非往数组里push重复数据。
  • 每个Radio.Group的value绑定对应表单id的选中值,保证组内单选。

2. 主Bucket(New Forms Identified)删除已移动项

原代码中NewFormsIdentified是常量,无法修改;同时删除逻辑removeHandler完全错误,无法正确定位要删除的项。

  • 将NewFormsIdentified转为useState状态,允许动态修改。
  • 在onSubmit中,收集所有选中要移动的项,然后过滤主Bucket列表,移除已选中的项。
  • 优化regulatoryData的更新逻辑,避免重复添加相同项。

3. 额外修复:全局编辑状态问题

原edit1是全局布尔值,导致点击编辑时所有表单同时切换编辑状态,改为记录当前编辑的表单id(editId),实现单个表单独立编辑。

修改后完整代码

import React, { useState } from "react";
import { Row, Col, Divider, Button, Radio } from "antd";

import { Hicon, uuid } from "utils/imports";
import styles from "./FormsToBeMaintained.module.css";

const FormsToBeMaintained = props => {
  const plainOptions = [
    {
      label: "Regulatory Forms",
      value: "Regulatory Forms"
    },
    {
      label: "Employer Specific Forms",
      value: "Employer Specific Forms"
    }
  ];
  // 改为state,允许动态修改主Bucket列表
  const [newFormsIdentified, setNewFormsIdentified] = useState([
    {
      id: 1,
      tittle: "W-4",
      "Regulatory Forms": true,
      "Employer Specific Forms": false,
      options: [
        { labelId: 3, label: "Regulatory Forms", value: "Regulatory Forms" },
        { labelId: 4, label: "Employer Specific Forms", value: "Employer Specific Forms" }
      ]
    },
    {
      id: 2,
      tittle: "State new hire tax forms",
      "Regulatory Forms": true,
      "Employer Specific Forms": false,
      options: [
        { labelId: 5, label: "Regulatory Forms", value: "Regulatory Forms" },
        { labelId: 6, label: "Employer Specific Forms", value: "Employer Specific Forms" }
      ]
    },
    {
      id: 3,
      tittle: "Offer letter",
      "Regulatory Forms": true,
      "Employer Specific Forms": false,
      options: [
        { labelId: 7, label: "Regulatory Forms", value: "Regulatory Forms" },
        { labelId: 8, label: "Employer Specific Forms", value: "Employer Specific Forms" }
      ]
    },
    {
      id: 4,
      tittle: "Employment agreement",
      "Regulatory Forms": true,
      "Employer Specific Forms": false,
      options: [
        { labelId: 9, label: "Regulatory Forms", value: "Regulatory Forms" },
        { labelId: 10, label: "Employer Specific Forms", value: "Employer Specific Forms" }
      ]
    },
    {
      id: 5,
      tittle: "Emergency contact information",
      "Regulatory Forms": true,
      "Employer Specific Forms": false,
      options: [
        { labelId: 11, label: "Regulatory Forms", value: "Regulatory Forms" },
        { labelId: 12, label: "Employer Specific Forms", value: "Employer Specific Forms" }
      ]
    }
  ]);
  const [radioChecked, isRadioChecked] = useState(false);
  // 改为对象,存储每个表单id对应的选中值
  const [selectedValues, setSelectedValues] = useState({});
  // 记录当前编辑的表单id,实现单个表单独立编辑
  const [editId, setEditId] = useState(null);
  const [regulatoryData, setRegulatoryData] = useState([]);

  // 更新单个表单的选中值
  const onChange1 = (formId, value) => {
    const newSelected = { ...selectedValues, [formId]: value };
    setSelectedValues(newSelected);
    // 只要有选中项,就激活保存按钮
    isRadioChecked(Object.values(newSelected).some(v => v));
  };

  const onSubmit = () => {
    // 收集所有选中要移动的项
    const movedItems = newFormsIdentified
      .filter(form => selectedValues[form.id])
      .map(form => ({
        id: form.id,
        name: form.tittle,
        value: selectedValues[form.id]
      }));

    // 合并到regulatoryData,避免重复添加
    setRegulatoryData(prev => {
      const existingIds = new Set(prev.map(item => item.id));
      return [...prev, ...movedItems.filter(item => !existingIds.has(item.id))];
    });

    // 从主Bucket移除已移动的项
    setNewFormsIdentified(prev =>
      prev.filter(form => !selectedValues[form.id])
    );

    // 清空选中状态,重置保存按钮
    setSelectedValues({});
    isRadioChecked(false);
  };

  // 取消编辑状态
  const cancelEdit = () => setEditId(null);

  return (
    <>
      <Row>
        <Col span={12} className={`${styles.outerBor} `}>
          <Row>
            <Col span={24} className={`text-size-18 ${styles.title} ${styles.section}`}>
              Regulated Forms
            </Col>
            <Divider />
          </Row>

          <Row className={` ${styles.scroll_content}`}>
            {regulatoryData.length > 0 ? (
              regulatoryData.map(form => {
                if (form.value === "Regulatory Forms") {
                  return (
                    <>
                      <Col span={24} className={styles.content} key={form.id}>
                        {editId === form.id ? (
                          <>
                            <Row>
                              <Col span={18}>
                                <b>{form.name}</b>
                              </Col>
                              <Col span={6} className="align-right">
                                <Hicon
                                  icon="Cancel"
                                  onClick={cancelEdit}
                                  className="text-size-24"
                                />
                                &nbsp;&nbsp;&nbsp;&nbsp;
                                <Hicon
                                  icon="SaveIconWithoutBackground"
                                  className="text-size-24"
                                  onClick={() => {
                                    // 编辑保存逻辑:更新当前项的分类
                                    cancelEdit();
                                  }}
                                />
                              </Col>
                            </Row>
                            <Row key={form.id}>
                              <Col span={24} className={` ${styles.content}`}>
                                <Radio.Group
                                  key={uuid()}
                                  options={plainOptions}
                                  value={form.value}
                                  onChange={(e) => {
                                    setRegulatoryData(prev =>
                                      prev.map(item =>
                                        item.id === form.id ? { ...item, value: e.target.value } : item
                                      )
                                    );
                                  }}
                                  className={` ${styles.radioContent} text-bold `}
                                />
                              </Col>
                            </Row>
                          </>
                        ) : (
                          <Row>
                            <Col span={20}>
                              <b>{form.name}</b>
                            </Col>
                            <Col span={4} className="align-right">
                              <Hicon
                                icon="Pencil"
                                className="text-size-24"
                                onClick={() => setEditId(form.id)}
                              />
                            </Col>
                          </Row>
                        )}
                      </Col>
                      <Divider />
                    </>
                  );
                }
                return null;
              })
            ) : (
              <Col span={24} className={styles.content}>
                <b>No Forms included</b>
              </Col>
            )}
          </Row>
        </Col>
        <Col span={12} className={`${styles.outerBor} `}>
          <Row>
            <Col span={24} className={`text-size-18 ${styles.title} ${styles.section}`}>
              Employer Specific Forms
            </Col>
            <Divider />
          </Row>
          <Row className={` ${styles.scroll_content}`}>
            {regulatoryData.length > 0 ? (
              regulatoryData.map(form => {
                if (form.value === "Employer Specific Forms") {
                  return (
                    <>
                      <Col span={24} className={styles.content} key={form.id}>
                        {editId === form.id ? (
                          <>
                            <Row>
                              <Col span={18}>
                                <b>{form.name}</b>
                              </Col>
                              <Col span={6} className="align-right">
                                <Hicon
                                  icon="Cancel"
                                  onClick={cancelEdit}
                                  className="text-size-24"
                                />
                                &nbsp;&nbsp;&nbsp;&nbsp;
                                <Hicon
                                  icon="SaveIconWithoutBackground"
                                  className="text-size-24"
                                  onClick={() => {
                                    // 编辑保存逻辑
                                    cancelEdit();
                                  }}
                                />
                              </Col>
                            </Row>
                            <Row key={form.id}>
                              <Col span={24} className={` ${styles.content}`}>
                                <Radio.Group
                                  key={uuid()}
                                  options={plainOptions}
                                  value={form.value}
                                  onChange={(e) => {
                                    setRegulatoryData(prev =>
                                      prev.map(item =>
                                        item.id === form.id ? { ...item, value: e.target.value } : item
                                      )
                                    );
                                  }}
                                  className={` ${styles.radioContent} text-bold `}
                                />
                              </Col>
                            </Row>
                          </>
                        ) : (
                          <Row>
                            <Col span={20}>
                              <b>{form.name}</b>
                            </Col>
                            <Col span={4} className="align-right">
                              <Hicon
                                icon="Pencil"
                                className="text-size-24"
                                onClick={() => setEditId(form.id)}
                              />
                            </Col>
                          </Row>
                        )}
                      </Col>
                      <Divider />
                    </>
                  );
                }
                return null;
              })
            ) : (
              <Col span={24} className={styles.content}>
                <b>No Forms included</b>
              </Col>
            )}
          </Row>
        </Col>
      </Row>
      <Row>
        <Col span={24} className={styles.outerBor}>
          <Row>
            <Col span={10} className={`text-size-18 text-bold ${styles.title} ${styles.section}`}>
              New Forms Identified
            </Col>
            <Col span={8} className={`text-size-18 text-bold ${styles.title} ${styles.section}`}>
              Move To
            </Col>

            <Col span={6} className={`text-size-18 ${styles.title} ${styles.section}`}>
              {radioChecked ? (
                <div className="align-right">
                  <Button
                    onClick={() => {
                      setSelectedValues({});
                      isRadioChecked(false);
                    }}
                    type="text"
                    className="text-size-14"
                  >
                    Cancel
                  </Button>
                  <Button
                    className={` border-radius-5 background_144182 text-size-14`}
                    type="primary"
                    onClick={onSubmit}
                  >
                    <Hicon icon="SaveIconWithoutBackground" className="text-size-16">
                      <span className="text-size-14">Save</span>
                    </Hicon>
                  </Button>
                </div>
              ) : (
                <Button
                  className={` border-radius-5 background_144182 text-size-14 align-right`}
                  type="primary"
                  disabled
                >
                  <Hicon icon="SaveIconWithoutBackground" className="text-size-16">
                    <span className="text-size-14">Save</span>
                  </Hicon>
                </Button>
              )}
            </Col>
          </Row>
          <Divider />
          <Row className={` ${styles.scroll_content}`}>
            {newFormsIdentified.length > 0 ? (
              newFormsIdentified.map(form => {
                return (
                  <>
                    <Col span={10} className={styles.content} key={form.id}>
                      <ul className="color_144182 text-bold">{form.tittle} </ul>
                    </Col>
                    <Col span={14} className={` ${styles.content}`}>
                      <Radio.Group
                        key={form.id}
                        onChange={(e) => onChange1(form.id, e.target.value)}
                        value={selectedValues[form.id] || undefined}
                        className={` ${styles.radioContent} text-bold `}
                      >
                        {form.options.map(opt => (
                          <Radio key={opt.labelId} value={opt.value}>{opt.value}</Radio>
                        ))}
                      </Radio.Group>
                    </Col>
                    <Divider />
                  </>
                );
              })
            ) : (
              <Col span={24} className={styles.content}>
                <b>No Forms available</b>
              </Col>
            )}
          </Row>
        </Col>
      </Row>
    </>
  );
};

export default FormsToBeMaintained;

内容的提问来源于stack exchange,提问作者Swapnil Bais

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 02:30:50