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

React中如何导入组件并修改其状态 实现段落转输入框编辑功能

实现方案

核心改动说明

  • 移除将JSX存入state的反模式,直接使用接口返回的原始用户数据渲染视图
  • 编辑逻辑完全封装在EditUser组件内,内部维护编辑状态、临时表单数据,仅通过props和父组件通信
  • 父组件仅需处理保存后的用户数据更新,无需感知编辑内部逻辑

修改后代码

UserList.jsx

import React, { useState, useEffect } from "react";
import EditUser from "./EditUser";

const UserList = () => {
  // 存储原始用户数据
  const [userList, setUserList] = useState([]);

  useEffect(() => {
    fetch("http://user/api/getEndpoint")
      .then((res) => res.json())
      .then((json_result) => {
        setUserList(json_result.results);
      })
      .catch(err => console.error("用户数据获取失败", err));
  }, []);

  // 处理编辑后的数据保存
  const handleSaveUser = (index, updatedUser) => {
    const newUserList = [...userList];
    newUserList[index] = updatedUser;
    setUserList(newUserList);
    // 如果需要提交修改到后端,可以在这里加调用接口的逻辑
  };

  return (
    <div>
      {userList.map((item, index) => (
        <div className="body" key={index}>
          <div>
            <img
              className="circle"
              src={item.picture.large}
              alt={`${item.name.first} ${item.name.last}`}
            />
            {/* 把用户数据和保存回调传给编辑组件 */}
            <EditUser 
              user={item} 
              onSave={(updated) => handleSaveUser(index, updated)} 
            />
            <hr />
          </div>
        </div>
      ))}
    </div>
  );
};

export default UserList;

EditUser.jsx

import React, { useState } from "react";

function EditUser({ user, onSave }) {
  // 内部维护编辑状态和临时表单数据
  const [isEditing, setIsEditing] = useState(false);
  const [formData, setFormData] = useState({
    name: { first: user.name.first, last: user.name.last },
    email: user.email,
    phone: user.phone,
    location: { city: user.location.city, state: user.location.state }
  });

  // 表单输入同步到临时数据
  const handleInputChange = (field, value, nestedField = null) => {
    if (nestedField) {
      setFormData({
        ...formData,
        [field]: { ...formData[field], [nestedField]: value }
      });
      return;
    }
    setFormData({ ...formData, [field]: value });
  };

  // 保存修改,调用父组件回调后退出编辑态
  const handleSave = () => {
    onSave(formData);
    setIsEditing(false);
  };

  // 编辑态渲染输入框
  if (isEditing) {
    return (
      <div className="list">
        <div className="title">
          <input
            value={formData.name.first}
            onChange={(e) => handleInputChange("name", e.target.value, "first")}
            placeholder="名"
          />
          <input
            value={formData.name.last}
            onChange={(e) => handleInputChange("name", e.target.value, "last")}
            placeholder="姓"
          />
        </div>
        <p className="text">
          <input
            value={formData.email}
            onChange={(e) => handleInputChange("email", e.target.value)}
            placeholder="邮箱"
          />
        </p>
        <p className="text">
          <input
            value={formData.phone}
            onChange={(e) => handleInputChange("phone", e.target.value)}
            placeholder="电话"
          />
        </p>
        <p className="text">
          <input
            value={formData.location.city}
            onChange={(e) => handleInputChange("location", e.target.value, "city")}
            placeholder="城市"
          />
          ,
          <input
            value={formData.location.state}
            onChange={(e) => handleInputChange("location", e.target.value, "state")}
            placeholder="省份"
          />
        </p>
        <div className="edit-actions">
          <button className="button save" onClick={handleSave}>保存</button>
          <button className="button cancel" onClick={() => setIsEditing(false)}>取消</button>
        </div>
      </div>
    );
  }

  // 非编辑态渲染展示文本+编辑按钮
  return (
    <div>
      <div className="list">
        <h5 className="title">
          {user.name.first} {user.name.last}
        </h5>
        <p className="text">{user.email}</p>
        <p className="text">{user.phone}</p>
        <p className="text">
          {user.location.city}, {user.location.state}
        </p>
      </div>
      <button
        className="button"
        onClick={() => setIsEditing(true)}
      >
        编辑用户
      </button>
    </div>
  );
}

export default EditUser;

关键逻辑说明

  • 所有编辑相关的状态(是否处于编辑态、临时表单数据)都存在EditUser组件内部,完全封装编辑逻辑,父组件无需感知
  • 仅当用户点击保存时,才会把修改后的数据通过onSave回调传给父组件更新全局用户列表,避免脏数据污染原始数据
  • 输入框的修改只会同步到临时的formData,点击取消会直接丢弃修改回退到原始展示内容

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 16:24:00