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

React表单更新时如何保留点击元素的当前数据状态?

解决React更新表单预填数据问题

你的核心问题是打开编辑模态框时没有加载对应服务的现有数据,导致表单为空。以下是两种可行的解决方案:

方案一:从父组件传入现有数据(推荐)

如果父组件已经持有服务列表数据,直接将当前要编辑的服务对象传入组件,避免重复请求接口:

  1. 修改组件接收的props,新增serviceData:
export default function UpdateService({ fetchData, id, serviceData }) {
  // ... 原有代码
}
  1. 修改handleShow方法,打开模态框时用传入的数据填充表单状态:
const handleShow = () => {
  setName(serviceData.name);
  setDesc(serviceData.description);
  setShow(true);
};

方案二:打开模态框时通过ID请求数据

如果父组件没有现成数据,就在打开模态框时主动请求接口获取:

  1. 修改handleShow为异步方法,添加数据获取逻辑:
const handleShow = async () => {
  try {
    const JWT = await getCookie("auth");
    const { data } = await axios(`/api/serviceType/${id}`, {
      headers: {
        Authorization: JWT,
      },
    });
    // 填充表单状态
    setName(data.name);
    setDesc(data.description);
    setShow(true);
  } catch (e) {
    alert("加载数据失败");
  }
};

额外修复点

原代码还有两处小问题需要修正:

  • 表单的onSubmit没有阻止默认行为,会导致页面刷新:
<Form onSubmit={(e) => {
  e.preventDefault();
  updateService(id);
}}>
  • 提交按钮应该放在<Form>标签内部,否则type="submit"不会触发表单的onSubmit事件

修改后的完整组件示例(以方案一为例):

import React, { useState, useEffect } from 'react';
import { getCookie } from "../../../utils/cookies";
import axios from "axios";
import Button from 'react-bootstrap/Button';
import Form from 'react-bootstrap/Form';
import Modal from 'react-bootstrap/Modal';
import { PencilSquare } from 'react-bootstrap-icons';

export default function UpdateService({ fetchData, id, serviceData }) {
  const [show, setShow] = useState(false);
  const [name, setName] = useState("");
  const [desc, setDesc] = useState("");
  const [isLoading, setIsLoading] = useState(true);
  const [data, setData] = useState([]);

  const isEnabled = name.length > 0 && desc.length > 0;

  const handleClose = () => setShow(false);
  const handleShow = () => {
    setName(serviceData.name);
    setDesc(serviceData.description);
    setShow(true);
  };

  const updateService = async (id) => {
     try {
       setIsLoading(true);
       const JWT = await getCookie("auth");
       const { data } = await axios(
         `/api/serviceType/${id}`, 
         {
           method: "PATCH",
           data: {
             name: name,
             description: desc,
           },
           headers: {
             "Content-Type": "application/json",
             Authorization: JWT,
           },
         }
       );
       setData(data);
       setShow(false);
       alert("更新成功");
     } catch (e) {
       alert("error updating data");
     } finally {
       setIsLoading(false);
     }
  };

  useEffect(() => {
    if (data.length > 0) {
      fetchData(data);
    }
  }, [data, fetchData]);

  return (
    <>
      <PencilSquare onClick={handleShow}/>

      <Modal show={show} backdrop="static" onHide={handleClose}>
        <Modal.Header closeButton>
          <Modal.Title>Update Service</Modal.Title>
        </Modal.Header>
        <Modal.Body>
          <Form onSubmit={(e) => {
            e.preventDefault();
            updateService(id);
          }}>
            <Form.Group className="mb-3" controlId="exampleForm.ControlInput1">
              <Form.Label>Service Name</Form.Label>
              <Form.Control
                type="text"
                value={name}
                placeholder="Service Name"
                autoFocus
                onChange={(e) => setName(e.target.value)}
              />
            </Form.Group>
            <Form.Group
              className="mb-3"
              controlId="exampleForm.ControlTextarea1"
            >
              <Form.Label>Description</Form.Label>
              <Form.Control 
                as="textarea" 
                rows={3}
                placeholder="Please describe this service"
                value={desc}
                onChange={(e) => setDesc(e.target.value)}
                />
            </Form.Group>
            <Modal.Footer>
              <Button variant="outline-dark" onClick={handleClose}>
                Cancel
              </Button>
              <Button type="submit" variant="dark" disabled={!isEnabled || isLoading}>
                {isLoading ? "Updating..." : "Update"}
              </Button>
            </Modal.Footer>
          </Form>
        </Modal.Body>
      </Modal>
    </>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 21:45:42