如何在React的TanStack Table中删除行后重新获取数据?
问题根源
你当前的操作逻辑是:发送DELETE请求 → 通过索引过滤本地状态移除行。但React组件卸载后本地状态会被完全销毁,当你从其他页面返回CategoryList.tsx时,组件会重新挂载,如果此时没有从服务器拉取最新的分类数据,而是复用了之前的旧数据源(比如初始化时的静态数据、未更新的缓存数据),就会导致已删除的行再次出现。
解决方案
以下是几个直接落地的修复方案,适配你的技术栈:
方案1:组件每次挂载都拉取最新数据
在CategoryList.tsx中,用useEffect监听组件挂载,确保每次进入页面(包括返回时)都重新请求服务器的最新分类列表,不要依赖本地状态留存旧数据:
import { useEffect, useState } from 'react'; import Table from './Table'; const CategoryList = () => { const [categories, setCategories] = useState([]); // 组件挂载(含返回时的重新挂载)就触发数据请求 useEffect(() => { const fetchLatestCategories = async () => { const res = await fetch('/api/categories'); const freshData = await res.json(); setCategories(freshData); }; fetchLatestCategories(); }, []); const handleDelete = async (categoryId: number) => { // 先确保后端删除成功 await fetch(`/api/categories/${categoryId}`, { method: 'DELETE' }); // 用ID过滤本地状态(比索引更可靠) setCategories(prev => prev.filter(cat => cat.id !== categoryId)); }; // 表格配置逻辑... return <Table data={categories} onDelete={handleDelete} />; }; export default CategoryList;
方案2:替换索引过滤为ID过滤(避免索引混乱)
你当前用rowIndex过滤的方式风险很高——如果列表有排序、分页或新增操作,索引会随时变化,导致过滤出错。改成用分类ID过滤,既稳定又能确保本地状态和后端数据一致:
// 替换原有的handleDelete逻辑 const handleDelete = async (categoryId: number) => { await fetch(`/api/categories/${categoryId}`, { method: 'DELETE' }); // 用唯一ID过滤,彻底避免索引导致的错误 setCategories(prev => prev.filter(cat => cat.id !== categoryId)); };
方案3:全局状态同步(适配有全局状态管理的场景)
如果你的应用用了Redux、Zustand等全局状态工具,可将分类数据存在全局状态中,删除操作同时更新全局状态,这样组件卸载再挂载时,会直接从全局状态获取最新数据:
// 以Zustand为例 import { useCategoryStore } from '../stores/categoryStore'; const CategoryList = () => { const { categories, fetchCategories, deleteCategory } = useCategoryStore(); useEffect(() => { fetchCategories(); }, []); const handleDelete = async (categoryId: number) => { // 全局store封装了"发请求+更新状态"的逻辑 await deleteCategory(categoryId); }; return <Table data={categories} onDelete={handleDelete} />; };
额外注意事项
- 先确认DELETE接口确实生效:用Postman或浏览器DevTools测试接口,检查数据库中的分类记录是否被真实删除。
- 如果用了React Query/SWR这类缓存工具,删除后要手动失效缓存,确保下次请求拿到最新数据:
// React Query示例 const { data: categories, refetch } = useQuery('categories', fetchCategories); const handleDelete = async (categoryId: number) => { await fetch(`/api/categories/${categoryId}`, { method: 'DELETE' }); refetch(); // 手动触发重新拉取 };
内容的提问来源于stack exchange,提问作者achraf amellal
相关产品推荐
相关产品推荐

