使用REDUX/RTK Query删除条目后如何实现页面自动刷新?
你遇到的问题根源是自定义的删除thunk没有和RTK Query的缓存体系打通,RTK Query感知不到后端数据已经发生变更,自然不会主动刷新查询结果,也不会更新组件渲染。
推荐解决方案:将删除逻辑改为RTK Query原生Mutation
这是最符合RTK Query设计规范的方案,不需要额外写监听逻辑,靠框架自带的缓存失效机制自动处理刷新。
1. 改造你的coinApi定义
给查询和删除操作配置标签关联,删除成功后自动触发列表查询重新拉取:
export const coinApi = createApi({ reducerPath: 'coinApi', baseQuery: fetchBaseQuery({ baseUrl }), // 定义标签类型,用于关联查询和变更操作 tagTypes: ['Coin'], endpoints: (builder) => ({ getCoins: builder.query({ query: () => createRequest(`/watchlist`), // 标记这个查询返回的是Coin类型的数据 providesTags: ['Coin'] }), // 新增删除币种的Mutation deleteCoin: builder.mutation({ query: (id) => ({ url: `/coins/watchlist/${id}`, method: 'DELETE' }), // 执行成功后失效所有标记为Coin的查询缓存,触发自动重新拉取 invalidatesTags: ['Coin'] }) }), }); // RTK Query会自动生成对应的hooks export const { useGetCoinsQuery, useDeleteCoinMutation } = coinApi;
2. 改造组件逻辑
删掉你之前自定义的deleteCoin thunk、相关的状态监听和无用的useEffect,直接用生成的mutation钩子:
const { data, isFetching } = useGetCoinsQuery(); // 调用删除的mutation钩子,直接拿到加载、错误状态 const [deleteCoin, { isLoading: loadingDelete, error: errorDelete }] = useDeleteCoinMutation(); if (isFetching) return <Loader></Loader>; const deleteHandler = (id) => { if (window.confirm('Are you sure?')) { // 直接调用mutation即可,删除成功后会自动刷新列表 deleteCoin(id); } };
兼容方案:如果不想改动现有自定义thunk
如果你需要保留现有删除逻辑,可以在删除成功后手动触发RTK Query缓存失效,主动让列表重新拉取:
在你现有的deleteCoin thunk的成功回调里,加一行触发缓存失效的逻辑:
await axios.delete(`/api/coins/watchlist/${id}`); dispatch({ type: COIN_DELETE_SUCCESS, }); // 新增这行,手动失效Coin标签对应的所有缓存 dispatch(coinApi.util.invalidateTags(['Coin']));
这种方式也能实现删除后自动刷新,不需要修改组件逻辑。
为什么你之前的尝试无效?
- 你把
useGetCoinsQuery返回的data作为useEffect依赖,但是data是RTK Query缓存的旧数据,没有触发重新拉取的前提下data不会发生变化,useEffect自然不会执行。 - 直接
useSelector取state.coinApi.queries拿到的也是缓存的旧查询结果,没有更新的前提下也不会触发组件重渲染。
内容的提问来源于stack exchange,提问作者deagleshot32
相关产品推荐
相关产品推荐

