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
相关产品推荐
相关产品推荐

