React表格删除行后无法刷新,reload状态引发参数未定义求助
问题:React删除用户后表格无法刷新,添加reload状态导致删除请求ID未定义
问题背景
这是一个从API获取数据生成表格的React组件,表格行的删除按钮会触发确认模态框。为避免组件首次渲染时误触发api.delete请求,通过useRef设置effectRan初始值为false。点击模态框的Delete按钮后,后端已成功删除用户,但前端表格未自动刷新。尝试添加reload状态作为useEffect依赖来触发重新获取数据,虽然能实现表格刷新,但会导致api.delete请求中的ida参数变为未定义。
原组件代码
import React, { Fragment, useEffect, useState, useRef } from "react"; ... other imports ... export default function AllUsers() { const api = useApi(); const [userData, setUserData] = useState(); const [showModal, setShowModal] = useState(false); const navigate = useNavigate(); const [modalMessage, setModalMessage] = useState(); const [removeUserId, setRemoveUserId] = useState(); const [ida, setIda] = useState(); let effectRan = useRef(false); const [reload, setReload] = useState(false); useEffect(() => { (async () => { const response = await api.get("/admin/users"); if (response.ok) { setUserData(response.body); } else { setUserData(null); } })(); }, [api]); useEffect(() => { if (effectRan.current) { (async () => { const response = await api.delete("/admin/users", { ida: ida, }); if (response.ok && response.status === 204) { console.log(response); } else { console.log(response.body.errors); } })(); } return () => (effectRan.current = true); }, [api, ida]); const handleEditClick = (e, rowIndex) => { navigate("/user/" + rowIndex.username, [navigate]); }; const handleRemoveClick = (e, rowIndex) => { setShowModal(true); setModalMessage({ title: `Remove ${rowIndex.username}`, message: `User's email to remove ${rowIndex.email}`, }); setRemoveUserId(rowIndex.id); }; const closeHandler = () => { setShowModal(false); }; const deleteHandler = () => { setIda(removeUserId); setShowModal(false); }; return ( <Fragment> {showModal && ( <BtModal show={showModal} title={modalMessage.title} message={modalMessage.message} handleClose={closeHandler} onConfirm={deleteHandler} /> )} <Body> <h1>User Table</h1> {userData === undefined ? ( <Spinner animation="border" /> ) : ( <> {userData === null ? ( <p>Could not retrieve users.</p> ) : userData.length === 0 ? ( <p>There are not users in system</p> ) : ( <UserListTable newData={userData} handleEditClick={handleEditClick} handleRemoveClick={handleRemoveClick} /> )} </> )} </Body> </Fragment> ); }
添加reload状态后的useEffect代码
useEffect(() => { (async () => { const response = await api.get("/admin/users"); if (response.ok) { setUserData(response.body); effectRan.current = false; } else { setUserData(null); } })(); }, [api, reload]); useEffect(() => { if (effectRan.current) { (async () => { const response = await api.delete("/admin/users", { ida: ida, }); if (response.ok && response.status === 204) { console.log(response); setReload(!reload); } else { console.log(response.body.errors); } })(); } return () => (effectRan.current = true); }, [api, ida, reload]);
解决方案
方案1:删除后直接更新本地数据(无需重复请求API)
无需依赖额外状态,删除成功后直接过滤本地数据,响应更快:
// 修改删除逻辑的useEffect useEffect(() => { // 增加ida存在的判断,避免无效请求 if (effectRan.current && ida) { (async () => { const response = await api.delete("/admin/users", { ida: ida, }); if (response.ok && response.status === 204) { // 直接过滤掉已删除的用户,更新本地状态 setUserData(prevData => prevData.filter(user => user.id !== ida)); } else { console.log(response.body.errors); } })(); } return () => (effectRan.current = true); }, [api, ida]);
方案2:修复reload状态导致的ida未定义问题
问题根源是setReload(!reload)触发useEffect重复执行时,ida可能因状态异步更新出现异常,调整依赖和更新逻辑:
// 获取数据的useEffect保持不变 useEffect(() => { (async () => { const response = await api.get("/admin/users"); if (response.ok) { setUserData(response.body); } else { setUserData(null); } })(); }, [api, reload]); // 删除逻辑的useEffect去掉reload依赖,用函数式更新reload useEffect(() => { if (effectRan.current && ida) { (async () => { const response = await api.delete("/admin/users", { ida: ida, }); if (response.ok && response.status === 204) { // 函数式更新确保拿到最新的reload状态 setReload(prev => !prev); // 重置ida,避免重复触发请求 setIda(null); } else { console.log(response.body.errors); } })(); } return () => (effectRan.current = true); }, [api, ida]);
方案3:简化逻辑,直接在deleteHandler中处理
去掉冗余的ida状态和中转的useEffect,直接在删除确认函数中完成请求和刷新:
// 删除原有的ida状态和第二个useEffect const deleteHandler = async () => { setShowModal(false); if (!removeUserId) return; const response = await api.delete("/admin/users", { ida: removeUserId, }); if (response.ok && response.status === 204) { // 本地更新数据(推荐) setUserData(prev => prev.filter(user => user.id !== removeUserId)); // 或者触发重新请求: // setReload(prev => !prev); } else { console.log(response.body.errors); } };
内容的提问来源于stack exchange,提问作者dannisis
相关产品推荐
相关产品推荐

