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

多客户端修改数据时,如何刷新RTK Query的缓存数据?

多用户场景下RTK Query缓存同步解决方案

针对你提到的10人规模ERP系统的缓存同步问题,以下是几个务实的解决方案,按实时性从高到低排序:

1. WebSocket实时推送(推荐用于强实时需求)

在后端添加WebSocket服务,当任意客户端完成资源更新(创建/修改/删除)后,后端主动向所有在线客户端广播更新事件。客户端收到事件后,立即调用RTK Query的缓存失效方法刷新数据。

示例代码(客户端WebSocket监听):

import { useEffect } from 'react';
import { useDispatch } from 'react-redux';
import { api } from './services/api';

function Dashboard() {
  const dispatch = useDispatch();

  useEffect(() => {
    const socket = new WebSocket('ws://your-api-domain/ws');
    
    socket.onmessage = (event) => {
      const updateData = JSON.parse(event.data);
      // 根据后端推送的实体类型,失效对应缓存标签
      if (updateData.entityType === 'orders') {
        dispatch(api.util.invalidateTags(['Orders']));
      } else if (updateData.entityType === 'customers') {
        dispatch(api.util.invalidateTags(['Customers']));
      }
    };

    socket.onclose = () => console.log('WebSocket连接关闭');
    return () => socket.close();
  }, [dispatch]);

  // ... 组件其余逻辑
}

后端只需在更新接口执行完成后,向WebSocket连接池广播实体更新类型即可(比如用Socket.io简化实现,避免原生WebSocket的兼容问题)。对于10人团队,这个方案的实现成本很低,且能保证数据即时同步。

2. 自动定期重验证(适合弱实时需求)

给RTK Query的查询配置自动重刷新规则,让客户端每隔一段时间主动拉取最新数据,无需后端额外开发。

示例代码(API Slice配置):

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

export const api = createApi({
  baseQuery: fetchBaseQuery({ baseUrl: '/api' }),
  endpoints: (builder) => ({
    getOrders: builder.query({
      query: () => '/orders',
      providesTags: ['Orders'],
      // 每30秒自动重新获取数据
      refetchInterval: 30000,
      // 组件挂载或查询参数变化时,自动重验证缓存
      refetchOnMountOrArgChange: true,
    }),
    getCustomers: builder.query({
      query: () => '/customers',
      providesTags: ['Customers'],
      refetchInterval: 60000, // 每分钟刷新一次客户数据
    }),
  }),
});

这个方案不需要后端改动,适合数据更新频率不高的场景。10个用户的请求量完全不会对API造成压力。

3. 手动全局刷新(辅助方案)

在仪表盘添加全局刷新按钮,允许用户主动触发全量或部分实体的缓存失效。同时可以在关键操作(比如提交表单后),自动触发对应实体的刷新。

示例代码(手动刷新逻辑):

import { useDispatch } from 'react-redux';
import { api } from './services/api';

function GlobalRefreshButton() {
  const dispatch = useDispatch();

  const handleRefresh = () => {
    // 失效所有核心实体的缓存标签
    dispatch(api.util.invalidateTags(['Orders', 'Customers', 'Inventory']));
  };

  return <button onClick={handleRefresh}>刷新所有数据</button>;
}

可以把这个按钮放在导航栏显眼位置,作为实时推送方案的 fallback,让用户在需要时主动获取最新数据。

4. 时间戳轮询(轻量替代方案)

如果不想引入WebSocket,可以定期请求后端的一个轻量接口,获取各实体的最新更新时间戳。客户端对比本地存储的时间戳,若不一致则触发对应缓存的失效。

示例代码(时间戳检查逻辑):

import { useEffect } from 'react';
import { useDispatch } from 'react-redux';
import { api } from './services/api';

function UpdateChecker() {
  const dispatch = useDispatch();

  useEffect(() => {
    const checkUpdates = async () => {
      const latestTimestamps = await fetch('/api/latest-updates').then(res => res.json());
      
      // 检查订单数据是否更新
      const cachedOrderTime = localStorage.getItem('lastOrderUpdate');
      if (latestTimestamps.orders !== cachedOrderTime) {
        dispatch(api.util.invalidateTags(['Orders']));
        localStorage.setItem('lastOrderUpdate', latestTimestamps.orders);
      }

      // 同理检查其他实体...
    };

    // 每分钟检查一次
    const interval = setInterval(checkUpdates, 60000);
    return () => clearInterval(interval);
  }, [dispatch]);

  return null;
}

后端的/api/latest-updates接口只需返回各实体的最后更新时间戳(比如从数据库查询最大更新时间),这个方案的带宽消耗极低,适合不想做WebSocket开发的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 18:28:36