使用react-table-v7时API表格删除行后需刷新页面的问题咨询
问题描述
我正在为基于API数据的表格开发删除行功能,删除请求已成功执行,但必须刷新页面才能更新表格行数据。我使用的是react-table-v7,请问出现该问题的原因是什么?该如何解决?
const useTableResource = () => { const {data} = apiData(); const resourcesData = data; const resourcesDataLength = resourcesData.length; const query = window.matchMedia('(max-width: 750px)'); const resourcesColumns = useMemo(() => [ {Header: 'Tittle', accessor: 'name'}, { id: 'delete', accessor: () => 'delete', disableSortBy: true, Cell: ({row}) => <div onClick={(event) => event.stopPropagation()} style={{ display: 'flex', justifyContent: 'center' }}> <DeleteModal delb={async () => { await axios.delete(`api/resources?_id=${row.original._id}`); }}/> </div> } ], []); const tableInstance = useTable({ columns: resourcesColumns, data: resourcesData, //here load the data for my table disableSortRemove: true, initialState: { sortBy: [{id: 'resourceType.name', desc: false}], pageSize: 10 } }, useSortBy, usePagination); return { tableInstance, resourcesColumns, resourcesDataLength }; }; export default useTableResource;
问题原因
- 数据未触发更新:你通过
apiData()获取的表格数据,在删除操作完成后没有重新拉取。react-table的渲染完全依赖传入的resourcesData,只要这个数据没有变化,表格就不会重新渲染新内容。 - 删除操作未联动数据刷新:当前的删除回调仅发送了删除请求,但没有在请求成功后触发数据重新获取或本地状态更新,导致组件一直使用旧的数据集。
解决方案
步骤1:确保apiData()支持手动刷新
假设你的apiData()是自定义请求Hook(比如基于react-query的useQuery或自行封装),需要让它返回一个刷新函数,用于删除后重新拉取最新数据。如果是react-query的useQuery,它自带refetch方法;如果是自定义Hook,需自行实现刷新逻辑。
步骤2:修改删除回调,触发数据刷新
在DeleteModal的delb回调中,删除成功后调用刷新函数,更新resourcesData,从而触发react-table重新渲染。
修改后的完整代码
const useTableResource = () => { // 假设apiData()返回data和refresh函数(根据实际Hook调整) const {data, refresh} = apiData(); const resourcesData = data; const resourcesDataLength = resourcesData?.length || 0; const query = window.matchMedia('(max-width: 750px)'); const resourcesColumns = useMemo(() => [ {Header: 'Tittle', accessor: 'name'}, { id: 'delete', accessor: () => 'delete', disableSortBy: true, Cell: ({row}) => ( <div onClick={(event) => event.stopPropagation()} style={{display: 'flex', justifyContent: 'center'}} > <DeleteModal delb={async () => { // 执行删除请求 await axios.delete(`api/resources?_id=${row.original._id}`); // 删除成功后刷新数据 await refresh(); }} /> </div> ) } ], []); const tableInstance = useTable({ columns: resourcesColumns, data: resourcesData || [], // 处理data为undefined的情况 disableSortRemove: true, initialState: { sortBy: [{id: 'resourceType.name', desc: false}], pageSize: 10 } }, useSortBy, usePagination); return { tableInstance, resourcesColumns, resourcesDataLength }; }; export default useTableResource;
备选方案:手动更新本地状态(不推荐,易数据不一致)
如果无法修改apiData(),可以用useState本地管理数据,删除后手动过滤已删除的行:
const useTableResource = () => { const {data: initialData} = apiData(); const [resourcesData, setResourcesData] = useState(initialData || []); const resourcesDataLength = resourcesData.length; const query = window.matchMedia('(max-width: 750px)'); const resourcesColumns = useMemo(() => [ {Header: 'Tittle', accessor: 'name'}, { id: 'delete', accessor: () => 'delete', disableSortBy: true, Cell: ({row}) => ( <div onClick={(event) => event.stopPropagation()} style={{display: 'flex', justifyContent: 'center'}} > <DeleteModal delb={async () => { await axios.delete(`api/resources?_id=${row.original._id}`); // 手动过滤掉已删除的行 setResourcesData(prev => prev.filter(item => item._id !== row.original._id)); }} /> </div> ) } ], []); const tableInstance = useTable({ columns: resourcesColumns, data: resourcesData, disableSortRemove: true, initialState: { sortBy: [{id: 'resourceType.name', desc: false}], pageSize: 10 } }, useSortBy, usePagination); return { tableInstance, resourcesColumns, resourcesDataLength }; }; export default useTableResource;
注意:备选方案无需重新请求,但可能出现前端与后端数据不一致的情况(比如删除请求失败但前端已移除行),因此优先推荐重新拉取数据的方案。
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

