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

React中AddItem模态框提交数据成功后无法关闭问题排查

问题根因

模态框无法关闭的核心原因是页面同时渲染了两个完全独立的AddItem组件实例,两个实例的props不互通:

  • 第一个实例写在NewInvoice.js的Button标签内,受itemOpen状态控制显隐,只传入了setitemOpen方法,没有传入往表格新增行的func方法,即使提交数据也无法写入表格。
  • 第二个实例硬编码在FormDataTable.js的返回结构中,默认常驻渲染不受状态控制,只传入了新增行的func方法,没有传入setitemOpen方法。

你之前交互的一直是第二个常驻的AddItem实例:它能正常调用func把数据写入表格,但是执行props.setitemOpen(false)时会直接触发setitemOpen is not a function的报错,根本无法修改控制显隐的状态,模态框自然无法关闭。
顺带一提你代码里还有个小问题:表格表头顺序和行内容渲染顺序不匹配,会导致列数据错位。

修复方案
  1. 删除FormDataTable.js中硬编码的<AddItem func={addRows}/>代码,移除多余的常驻模态框实例。
  2. 将表格数据状态从FormDataTable提升到父组件NewInvoice中管理,让受控的AddItem实例同时拿到新增数据、关闭模态框两个方法。

修正后代码参考

NewInvoice.js

const [itemOpen, setitemOpen] = useState(false);
// 提升表格数据状态到父组件
const [tableData, setTableData] = useState([]);

// 新增行方法移到父组件
const addRows = (data) => {
  const totalData = tableData.length;
  data.id = totalData + 1;
  setTableData([...tableData, data]);
};

return (
  <>
    <div className="new-invoice-client">
      {/* 把表格数据传给子组件渲染 */}
      <FormDataTable tableData={tableData}/>
    </div>
    <div
      className="new-item-links"
      style={{ marginLeft: "35px", marginTop: "35px" }}
    >
      <Button onClick={() => setitemOpen(true)}>
        <BsPlus />
        Add an Item
        {/* 受控模态框同时传入两个方法 */}
        {itemOpen && <AddItem setitemOpen={setitemOpen} func={addRows} />}
      </Button>
    </div>
  </>
)

FormDataTable.js

function FormDataTable(props) {
  // 移除本地tableData状态和addRows方法、移除多余的AddItem实例
  const tableRows = props.tableData.map((value, index) => {
    return (
      <tr key={index}>
        {/* 对齐表头顺序 */}
        <td>{value.item}</td>
        <td>{value.description}</td>
        <td>{value.quantity}</td>
        <td>{value.rate}</td>
        <td>{value.amount}</td>
      </tr>
    );
  });

  return (
    <React.Fragment>
      <table className="table">
        <thead>
          <tr>
            <th>Item</th>
            <th>Description</th>
            <th>Qty</th>
            <th>Rate</th>
            <th>Amount</th>
          </tr>
        </thead>
        <tbody>{tableRows}</tbody>
      </table>
    </React.Fragment>
  );
}

可选优化

AddItem组件中注释掉的clearState()方法可以在提交逻辑中放开,保存成功后清空表单输入,下次打开模态框不会残留上次的填写内容:

const handleSubmit = (event) => {
  event.preventDefault();
  const formInputData = {item, amount, rate, quantity, description};
  props.func(formInputData);
  clearState(); // 放开清空表单逻辑
  props.setitemOpen(false);
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 06:30:38