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

如何在RTK Query中缓存数据同时持久化历史数据到Redux Store?

解决RTK Query缓存数据同时保存历史记录的方案

方案一:使用RTK Query内置的onQueryStarted生命周期函数

这是最直接的方案,无需额外中间件,直接在API Slice的Endpoint配置中处理查询结果,同时不影响RTK Query的缓存逻辑。

实现步骤:

  1. 定义存储历史电压数据的Slice:
import { createSlice } from '@reduxjs/toolkit';

const voltageHistorySlice = createSlice({
  name: 'voltageHistory',
  initialState: { history: [] },
  reducers: {
    addVoltageHistory: (state, action) => {
      // 可选:限制历史记录长度,比如只保留最近100条
      state.history = [...state.history, action.payload].slice(-100);
    }
  }
});

export const { addVoltageHistory } = voltageHistorySlice.actions;
export default voltageHistorySlice.reducer;
  1. 在RTK Query API Slice中给getVoltage Endpoint添加onQueryStarted回调:
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
import { addVoltageHistory } from './voltageHistorySlice';

const api = createApi({
  baseQuery: fetchBaseQuery({ baseUrl: '/api' }),
  endpoints: (builder) => ({
    getVoltage: builder.query({
      query: () => '/voltage',
      // 拦截查询成功的结果
      async onQueryStarted(args, { dispatch, queryFulfilled }) {
        try {
          // 等待查询完成拿到数据
          const { data } = await queryFulfilled;
          // 分发action将数据存入历史记录Slice
          dispatch(addVoltageHistory({
            value: data.voltage,
            timestamp: Date.now()
          }));
        } catch (err) {
          // 可选:处理查询失败的情况
          console.error('电压数据获取失败:', err);
        }
      }
    })
  })
});

export const { useGetVoltageQuery } = api;
export default api;

方案二:使用RTK Listener Middleware监听RTK Query的成功Action

如果需要更灵活的全局监听逻辑(比如同时处理多个Endpoint的结果),可以用Listener Middleware,但要注意监听的是RTK Query自动生成的成功Action类型,而非Hook本身。

实现步骤:

  1. 配置Listener Middleware并添加监听逻辑:
import { configureStore } from '@reduxjs/toolkit';
import { api } from './apiSlice';
import voltageHistoryReducer from './voltageHistorySlice';
import { createListenerMiddleware } from '@reduxjs/toolkit';
import { addVoltageHistory } from './voltageHistorySlice';

const listenerMiddleware = createListenerMiddleware();

// 监听getVoltage查询成功的Action
listenerMiddleware.startListening({
  actionCreator: api.endpoints.getVoltage.matchFulfilled,
  effect: async (action, listenerApi) => {
    // action.payload就是RTK Query返回的电压数据
    const voltageData = action.payload;
    // 分发action保存到历史记录
    listenerApi.dispatch(addVoltageHistory({
      value: voltageData.voltage,
      timestamp: Date.now()
    }));
  }
});

export const store = configureStore({
  reducer: {
    [api.reducerPath]: api.reducer,
    voltageHistory: voltageHistoryReducer
  },
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware()
      .concat(api.middleware)
      .prepend(listenerMiddleware.middleware)
});

方案对比

  • 方案一:代码简洁,与Endpoint绑定紧密,适合单个Endpoint的专属处理逻辑,无需额外配置中间件。
  • 方案二:灵活性更高,可统一处理多个Endpoint的结果,或添加复杂条件判断逻辑,但需要额外配置Listener Middleware。

两种方案都能保证RTK Query正常处理缓存,同时将数据持久化到自定义Store Slice中,满足查看当前电压和绘制历史波动图的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 11:50:00