如何让React在向数据库POST或DELETE后自动重新从API拉取数据?
React操作后自动更新渲染解决方案
核心问题原因
你遇到的问题主要是两点:
- React要求状态更新必须是不可变修改,直接修改原状态/调用状态更新函数的方法不会触发重渲染
- 你更新状态时没有匹配原有的数据结构,导致后续读取数据失效
1. DELETE操作代码修改
你原来的data是外层对象,图书列表存在data.data字段,更新时不能直接把整个状态替换为数组,要保留原结构:
function BookList({ data, isPending, setData }) { if (isPending){ return <p>Data Loading!</p> } const handleDelete = (book_id) => { fetch(`http://localhost:3000/books/${book_id}`, { method: 'DELETE' }) .then(response => response.json()) .then(()=> { // 保留外层对象结构,仅更新data字段的数组 const updatedBooks = data.data.filter(item => item.book_id !== book_id) setData({...data, data: updatedBooks}) }) } const rows = data.data.map(({book_id, book_title, author}, index) => ( <tr key={book_id}> {/* 加上key避免React警告 */} <td>{book_id}</td> <td>{book_title}</td> <td>{author}</td> <td> {/* button放到td里避免HTML结构错误 */} <button onClick={()=> handleDelete(book_id)}>Delete</button> </td> </tr> )) return ( <div> <table> <thead> <tr> <th>Id</th> <th>Title</th> <th>Author</th> <th>Delete</th> </tr> </thead> <tbody>{rows}</tbody> </table> </div> ); } export default BookList;
2. POST操作代码修改
你原来错误调用了setData.push,setData是状态更新函数不是数组,而且要获取后端返回的完整带id的图书数据再更新状态:
import { useState } from "react"; function NewBook({data, setData}) { const initialFormState = { book_title: "", author: "" }; const [formData, setFormData] = useState({ ...initialFormState }); const handleChange = ({ target }) => { setFormData({ ...formData, [target.name]: target.value }); }; const handleSubmit = (event) => { event.preventDefault(); const newBook = formData; const url = "http://localhost:3000/books"; const requestOptions = { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(newBook), }; fetch(url, requestOptions) .then((response) => response.json()) // 拿到后端返回的完整新图书数据(带自动生成的book_id) .then((savedNewBook) => { // 不可变方式更新状态,保留原结构追加新数据 setData(prev => ({ ...prev, data: [...prev.data, savedNewBook] })) console.log("Submitted Successfully") }) .catch((error) => console.log("Form submit error", error)); setFormData({ ...initialFormState }); }; // 剩余的表单渲染代码按原有逻辑补充即可 }
更稳妥的替代方案
如果你的自定义useFetch钩子暴露了refetch重新请求方法,更建议你操作完成后直接调用refetch()从后端拉取最新数据,避免手动修改状态和后端数据不一致的问题。
内容的提问来源于stack exchange,提问作者Chris Gilbert
相关产品推荐
相关产品推荐

