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

如何用react-query正确处理返回not_modified的API缓存逻辑?

React Query 处理带 ifModifiedSince 的 API 响应

你的核心问题在于两点:一是查询函数错误依赖了 useQuery 返回的 data(该值在查询执行时可能未更新),二是遇到 not_modified 响应时,无法正确获取缓存中的有效旧数据(此时缓存已被新的空响应覆盖)。以下是正确的实现方式:

1. 修复查询函数:从缓存读取 lastModified

不要直接使用 useQuery 返回的 data,而是通过 queryClient 直接读取缓存中的最新有效数据,确保每次请求都能传递正确的 ifModifiedSince 参数。

2. 处理 not_modified 响应:保留旧数据

在查询流程中拦截 not_modified 响应,返回缓存中的有效数据,避免缓存被空响应覆盖。

完整代码示例

import { useQuery, QueryClient } from '@tanstack/react-query';

// 定义类型(根据实际场景调整)
type TodoItem = { userId: number; id: number; title: string; completed: boolean };
type GetTodosOkResponse = { status: 'ok'; todos: TodoItem[]; lastModified: string };
type GetTodosNotModifiedResponse = { status: 'not_modified' };
type GetTodosResponse = GetTodosOkResponse | GetTodosNotModifiedResponse;

const todosQueryKey = ['todos'];

export const useTodos = (queryClient: QueryClient) => {
  return useQuery({
    queryKey: todosQueryKey,
    queryFn: async () => {
      // 从缓存获取上次的有效修改时间
      const cachedValidData = queryClient.getQueryData<GetTodosOkResponse>(todosQueryKey);
      const lastModified = cachedValidData?.lastModified || '';
      
      const response = await getTodos({ ifModifiedSince: lastModified });
      
      // 若返回未修改,直接返回缓存的有效数据(无缓存则返回原响应)
      if (response.status === 'not_modified') {
        return cachedValidData || response;
      }
      
      return response;
    },
    select: (data): GetTodosOkResponse | undefined => {
      if (!data || data.status === 'not_modified') return undefined;
      
      // 排序时创建新数组,避免原地修改缓存原始数据
      const sortedTodos = [...data.todos].sort((a, b) => b.id - a.id);
      return { ...data, todos: sortedTodos };
    },
    refetchInterval: 5000,
    staleTime: Infinity,
    // 确保重查时始终保留之前的有效数据
    keepPreviousData: true,
  });
};

关键细节说明

  • 缓存读取逻辑:通过 queryClient.getQueryData 获取缓存中的有效数据,保证每次请求的 ifModifiedSince 参数都是最新的修改时间。
  • not_modified 响应处理:在查询函数内直接返回缓存数据,避免 React Query 用空响应覆盖缓存,后续 select 可直接处理有效数据。
  • 不可变排序:使用 [...data.todos] 创建新数组后再排序,符合 React 状态管理的不可变性原则,避免意外修改缓存数据。
  • 状态稳定性:keepPreviousData: true 确保重查过程中组件始终能拿到之前的有效数据,不会出现空白或闪烁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 06:56:54