求助:无法通过React Hooks更新JSONPlaceholder数据
React Hooks + Fetch PUT更新JSONPlaceholder数据问题修复
问题根源分析
- Update组件无本地状态管理:未跟踪用户输入的修改值,表单提交时无法正确获取最新输入
- 参数传递与请求体错误:
onUpdate函数参数格式不匹配,PUT请求体写死字符串而非变量 - 父组件状态未同步:PUT请求成功后未更新App组件的
users数组,页面无法刷新显示修改后的数据 - 表单提交逻辑错误:Update组件表单未绑定
onSubmit,按钮未触发提交,输入框无初始值 - 组件方法传递遗漏:Album组件未将App的
onUpdate传递给Update组件,导致无法触发全局状态更新
修改后的完整代码
App.js
import './App.css'; import Create from "./Create"; import Album from "./Album"; import { useState, useEffect } from 'react' function App() { const [users, setData] = useState([]); useEffect(() => { fetchData(); }, []); const fetchData = async () => { await fetch("https://jsonplaceholder.typicode.com/albums") .then((res) => res.json()) .then((data) => setData(data)) .catch((err) => console.log(err)); }; const onAdd = async (title, userId) => { const url = "https://jsonplaceholder.typicode.com/albums/" await fetch(url, { method: "POST", body: JSON.stringify({ title, userId }), headers: { "Content-type": "application/json; charset=UTF-8" }, }) .then((res) => res.status === 201 && res.json()) .then((data) => data && setData(prev => [...prev, data])) .catch((err) => console.log(err)); }; // 修改onUpdate:接收id、title、userId,请求成功后更新本地状态 const onUpdate = async (id, title, userId) => { fetch(`https://jsonplaceholder.typicode.com/albums/${id}`, { method: 'PUT', body: JSON.stringify({ title, userId, id }), // 携带id确保接口返回正确数据 headers: { 'Content-type': 'application/json; charset=UTF-8' }, }) .then((response) => response.json()) .then((updatedItem) => { // 更新users数组中对应id的项 setData(prevUsers => prevUsers.map(item => item.id === id ? updatedItem : item )); }) .catch((err) => console.log(err)); }; const onDelete = async (id) => { await fetch(`https://jsonplaceholder.typicode.com/albums/${id}`, { // 修正接口路径:users改为albums method: "DELETE", }) .then((res) => { if (res.status === 200) { setData(users.filter(item => item.id !== id)); } }) .catch((err) => console.log(err)); }; return ( <div className="App"> <h3>React Crud Using Jsonplaceholder</h3> <br /> <Create onAdd={onAdd} /> <h3>There are total {users.length} albums </h3> <div> {users.map((item) => ( <Album id={item.id} key={item.id} title={item.title} userId={item.userId} onDelete={onDelete} onUpdate={onUpdate} // 传递onUpdate方法 /> ))} </div> </div> ); }; export default App;
Update.js
import { useState, useEffect } from 'react' export default function Update({ id, initialUserId, initialTitle, onUpdate }){ // 本地状态跟踪输入值 const [userId, setUserId] = useState(''); const [title, setTitle] = useState(''); // 初始化输入框值为传入的原始数据 useEffect(() => { setUserId(initialUserId.toString()); setTitle(initialTitle); }, [initialUserId, initialTitle]); const handleOnSubmit = (e) => { e.preventDefault(); // 调用父组件传递的onUpdate,传递正确参数 onUpdate(id, title, parseInt(userId)); // 清空输入框 setTitle(''); setUserId(''); } return( <div> <form onSubmit={handleOnSubmit}> <h3>Update Album</h3> <input name="userId" type="number" placeholder="userId" value={userId} onChange={(e) => setUserId(e.target.value)} /> <input name="title" type="text" placeholder="title" value={title} onChange={(e) => setTitle(e.target.value)} /> <button type="submit">Update</button> <hr /> </form> </div> ) }
Album.js
import { useState } from 'react' import Update from './Update' export default function Album({ id, title, userId, onDelete, onUpdate }){ const handleDelete = () => onDelete(id); const [showUpdate, setShowUpdate] = useState(false); return ( <div className="albumArt"> <h2>{title}</h2> <p>{userId}</p> <span> <button onClick={() => setShowUpdate(!showUpdate)}>edit</button> <button onClick={handleDelete}>delete</button> </span> {/* 传递初始值和父组件的onUpdate */} {showUpdate && <Update id={id} initialUserId={userId} initialTitle={title} onUpdate={onUpdate} />} </div> ) }
Create.js
export default function Create({ onAdd }){ const handleOnSubmit = (e) => { e.preventDefault(); onAdd(e.target.title.value, parseInt(e.target.userId.value)); e.target.title.value = ""; e.target.userId.value = ""; } return( <div> <form onSubmit={handleOnSubmit}> <h3>Add Album</h3> <input placeholder="title" name="title" /> <input placeholder="userId" name="userId" type="number" /> <button type="submit">Add</button> <hr /> </form> </div> ) }
关键修复点说明
- Update组件新增本地状态:用
useState跟踪输入框的title和userId,确保能获取用户修改的内容 - 修正onUpdate参数与请求体:App中的
onUpdate接收三个参数,请求体使用变量而非固定字符串,成功后通过map更新users数组对应项 - 同步组件间方法传递:Album组件将App的
onUpdate传递给Update,确保修改能触发全局状态更新 - 完善表单逻辑:Update组件表单绑定
onSubmit,按钮设置type="submit",输入框绑定value和onChange,并通过useEffect初始化显示原始数据 - 修正删除接口路径:原代码删除请求错用了
users接口,改为albums接口
内容的提问来源于stack exchange,提问作者Sai Sri Laxman Jangala
相关产品推荐
相关产品推荐

