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

React CRUD操作更新异常:编辑第二条未修改时保存第一条旧数据

问题修复方案

问题根源

你的代码存在3个核心问题导致数据覆盖:

  • updateProductType 状态没有在每次打开编辑弹窗时重置,第一次修改第一条数据后,该状态会一直留存第一条的修改值,后续打开其他数据的编辑弹窗只要不手动修改输入框,提交时就会把旧值传给接口
  • 编辑Modal被嵌套在列表的map循环中,每一条数据都会渲染一个重复的Modal,不仅冗余还会导致状态匹配错乱
  • 输入框使用了defaultValue实现非受控模式,打开新的编辑项时不会自动同步更新updateProductType状态

修复步骤

  1. 将编辑Modal从map循环中移出,全局只保留一个Modal实例
  2. 打开编辑弹窗的updatehandleShow方法中,同时给updateProductType赋值当前选中数据的原值,清空之前的残留值
  3. 将输入框的defaultValue改为value,改成受控组件和updateProductType绑定
  4. 关闭弹窗时额外清空updateProductType和updateid状态,避免残留

关键修改代码

// 修改打开编辑弹窗的方法
const updatehandleShow = (_id, att_value) => {
  updatesetShow(true);
  setupdateid({ id: _id, att_value: att_value });
  // 同步更新编辑状态为当前选中值
  setupdateProductType(att_value);
};

// 修改关闭弹窗的方法
const updatehandleClose = () => {
  updatesetShow(false);
  // 清空残留状态
  setupdateid({});
  setupdateProductType("");
};

输入框修改为受控模式:

<FormControl
  value={updateProductType}
  aria-label="Username"
  aria-describedby="basic-addon1"
  onChange={(e) => setupdateProductType(e.target.value)}
/>

同时把整个Modal组件移到map循环外,放在Card组件后面即可。

完整修复后代码

import {
  Button,
  Card,
  Col,
  FormControl,
  InputGroup,
  Modal,
  Row,
  Table,
} from "@themesberg/react-bootstrap";
import React, { useEffect, useState } from "react";

import axios from "axios";

import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";

const Bpm = () => {
  const [value, setValue] = useState([]);
  const [updateProductType, setupdateProductType] = useState("");

  const [show, setShow] = useState(false);
  const [addProduct, setaddProduct] = useState("");

  useEffect(() => {
    fetchData();
  }, []);

  const fetchData = async () => {
    await axios
      .get(`${process.env.REACT_APP_API_URL}/attributes/3`)
      .then((response) => {
        setValue(response.data);
      });
  };

  const handleClose = () => setShow(false);
  const handleShow = () => setShow(true);

  const [updateshow, updatesetShow] = useState(false);
  const [updateid, setupdateid] = useState({});

  const updatehandleClose = () => {
    updatesetShow(false);
    setupdateid({});
    setupdateProductType("");
  };
  const updatehandleShow = (_id, att_value) => {
    updatesetShow(true);
    setupdateid({ id: _id, att_value: att_value });
    setupdateProductType(att_value);
  };

  const handleUpdate = async (e) => {
    e.preventDefault();
    await axios
      .patch(`${process.env.REACT_APP_API_URL}/attributes/`, {
        _id: updateid.id,
        att_type: 3,
        att_value: updateProductType,
      })
      .then((res) => console.log("updated"));
    fetchData();
    updatehandleClose();
  };

  const attributeName = "BPM";

  return (
    <>
      <Card border="light" className="shadow-sm mb-4">
        <Card.Body className="pb-0">
          <Table
            responsive
            className="table-centered table-nowrap rounded mb-0"
          >
            <thead className="thead-light">
              <tr>
                <th className="border-0">#</th>
                <th className="border-0">BPM</th>
                <th className="border-0"></th>
              </tr>
            </thead>
            <tbody>
              {value.map((pt, index) => {
                const { att_value, _id } = pt;
                return (
                  <tr key={_id}>
                    <td>
                      <Card.Link href="#" className="text-primary fw-bold">
                        {index + 1}
                      </Card.Link>
                    </td>
                    <td className="fw-bold">
                      <FontAwesomeIcon />
                      {att_value}
                    </td>
                    <td style={{ width: "380px" }}>
                      <Row className="d-flex align-items-center">
                        <Col xs={12} xl={2} className="px-0">
                          <small className="fw-bold">
                            <Button
                              onClick={() => updatehandleShow(_id, att_value)}
                            >
                              编辑
                            </Button>
                          </small>
                        </Col>
                      </Row>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </Table>
        </Card.Body>
      </Card>
      {/* 编辑Modal移到循环外 */}
      <Modal show={updateshow} onHide={updatehandleClose}>
        <Modal.Header closeButton>
          <Modal.Title>{`编辑${attributeName}`}</Modal.Title>
        </Modal.Header>
        <form onSubmit={handleUpdate}>
          <Modal.Body>
            <InputGroup>
              <FormControl
                value={updateProductType}
                aria-label="属性值"
                aria-describedby="basic-addon1"
                onChange={(e) => setupdateProductType(e.target.value)}
              />
            </InputGroup>
          </Modal.Body>
          <Modal.Footer>
            <Button
              variant="secondary"
              onClick={updatehandleClose}
            >
              关闭
            </Button>
            <Button variant="primary" type="submit">
              保存修改
            </Button>
          </Modal.Footer>
        </form>
      </Modal>
    </>
  );
};

export default Bpm;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 14:27:03