You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在RTK Query中获取历史数据以实现删除项通知?

更贴合RTK的实现方案

方案1:使用RTK Query的onCacheEntryAdded生命周期钩子

这个钩子允许你直接介入缓存的创建与更新流程,方便对比新旧数据:

  • 在调用useGetSomeDataQuery时传入queryOptions,配置onCacheEntryAdded
  • 通过cacheDataLoaded获取初始缓存数据,再通过updateCachedData监听后续的缓存更新
  • 每次缓存更新时,对比新旧数据找出被移除的ID,触发通知逻辑
const { data, isLoading } = useGetSomeDataQuery(undefined, {
  onCacheEntryAdded: async (args, { cacheDataLoaded, cacheEntryRemoved, updateCachedData }) => {
    let currentData = await cacheDataLoaded;
    
    const unsubscribe = updateCachedData((newData) => {
      // 筛选出被移除的ID
      const removedIds = currentData.filter(item => !newData.some(newItem => newItem.id === item.id)).map(item => item.id);
      removedIds.forEach(id => {
        // 替换成你的通知逻辑,比如调用全局通知函数
        console.log(`ID为${id}的项已处理并从队列中移除`);
      });
      // 更新当前数据为最新值,供下次对比使用
      currentData = newData;
      return newData;
    });

    await cacheEntryRemoved;
    unsubscribe();
  }
});

方案2:自定义RTK中间件全局处理

如果多个组件都需要这类逻辑,自定义中间件可以实现全局监听:

  • 监听RTK Query的fulfilled类型action,筛选目标接口的更新事件
  • 获取旧缓存数据和新返回数据,对比差异后触发通知
const cacheDiffMiddleware = store => next => action => {
  // 匹配目标接口的成功action
  if (action.type.endsWith('/fulfilled') && action.meta.arg.endpointName === 'getSomeData') {
    const state = store.getState();
    const oldData = state.api.queries.getSomeData?.data;
    const newData = action.payload;
    
    if (oldData && newData) {
      const removedIds = oldData.filter(item => !newData.some(newItem => newItem.id === item.id)).map(item => item.id);
      removedIds.forEach(id => {
        // 这里可以dispatch一个显示通知的action,或者调用通知工具
        store.dispatch(showNotification(`ID为${id}的项已处理并从队列中移除`));
      });
    }
  }
  return next(action);
};

// 在configureStore时添加该中间件
const store = configureStore({
  reducer: {
    api: api.reducer,
    // 其他reducer
  },
  middleware: getDefaultMiddleware => 
    getDefaultMiddleware().concat(api.middleware, cacheDiffMiddleware),
});

方案3:使用useQuerySubscription订阅缓存更新

useQuerySubscription是专门用于订阅查询缓存变化的钩子,适配轮询这类持续更新场景:

  • 订阅目标接口的缓存更新,每次有新数据时触发onCacheUpdated回调
  • 在回调中直接获取oldData和newData,对比后处理通知
import { useQuerySubscription } from '@reduxjs/toolkit/query/react';
import { api } from './yourApiSlice';

const QueueComponent = () => {
  const { data, isLoading } = useGetSomeDataQuery();

  useQuerySubscription(api.endpoints.getSomeData, {
    onCacheUpdated: (args, { oldData, newData }) => {
      if (!oldData || !newData) return;
      
      const removedIds = oldData.filter(item => !newData.some(newItem => newItem.id === item.id)).map(item => item.id);
      removedIds.forEach(id => {
        // 执行你的通知逻辑
        alert(`ID为${id}的项已处理并从队列中移除`);
      });
    }
  });

  // 组件渲染代码
};

以上方案都无需额外使用useState存储本地状态,完全基于RTK生态的缓存机制实现,更符合RTK的设计理念,也能避免本地状态与缓存不同步的问题。

内容的提问来源于stack exchange,提问作者Sergei Basharov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 06:43:32