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

如何用react-query 4处理队列:逐个处理并移除已处理数据

React Query 4 本地缓存移除已处理队列项方案

核心思路

直接通过 React Query 的 queryClient.setQueryData 方法修改对应查询键的缓存数据,将已处理项从缓存数组中移除。组件无需额外维护索引,直接从 useQuery 返回的缓存数据中取第一项展示即可。

具体实现步骤

1. 获取 QueryClient 实例

在需要操作缓存的组件或自定义 Hook 中,通过 useQueryClient 钩子拿到 QueryClient 对象,用于后续操作缓存。

2. 编写处理队列项的 Mutation

在用户完成左滑/右滑操作后,触发修改服务器数据的 Mutation,并在回调中同步更新本地缓存,移除已处理的队列项。

3. 调整组件展示逻辑

不再依赖 useContext 维护索引,直接从 useQuery 返回的 data 中取第一个元素作为当前展示项——缓存数组每次处理后都会移除首项,新的首项自然就是下一个待处理内容。

代码示例

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

// 模拟处理队列项的服务器请求
const processQueueItem = async (queueItem: QueueObject) => {
  return fetchAuth(`/queue/${queueItem.id}/process`, {
    method: 'POST',
    body: JSON.stringify({ status: 'processed' })
  });
};

function QueueDisplayComponent({ queueType }: { queueType: QueueType }) {
  const queryClient = useQueryClient();
  const queryKey = ['getQueue', queueType];
  
  // 获取队列缓存数据
  const { data: queueData } = useMyQueue(queueType);
  
  // 处理队列项的 Mutation
  const processMutation = useMutation({
    mutationFn: processQueueItem,
    onSuccess: () => {
      // 更新缓存:移除第一个已处理项
      queryClient.setQueryData<QueryReturnQueue>(queryKey, (oldData) => {
        if (!oldData || !Array.isArray(oldData)) return oldData;
        // 复制原数组并移除首项,避免直接修改缓存原数据
        const newQueue = [...oldData];
        newQueue.shift();
        // 数组为空时返回 false,匹配你的类型定义
        return newQueue.length > 0 ? newQueue : false;
      });
    },
    // 可选:启用乐观更新,用户操作后立即更新缓存,失败时回滚
    // onMutate: async (queueItem) => {
    //   await queryClient.cancelQueries({ queryKey });
    //   const oldData = queryClient.getQueryData<QueryReturnQueue>(queryKey);
    //   // 立即更新缓存
    //   queryClient.setQueryData<QueryReturnQueue>(queryKey, (old) => {
    //     if (!old || !Array.isArray(old)) return old;
    //     const newQueue = [...old];
    //     newQueue.shift();
    //     return newQueue.length > 0 ? newQueue : false;
    //   });
    //   return { oldData };
    // },
    // onError: (_err, _variables, context) => {
    //   if (context?.oldData) {
    //     queryClient.setQueryData(queryKey, context.oldData);
    //   }
    // }
  });

  // 当前待展示的队列项
  const currentItem = Array.isArray(queueData) ? queueData[0] : null;

  const handleProcess = () => {
    currentItem && processMutation.mutate(currentItem);
  };

  if (!currentItem) {
    return <div>队列已空</div>;
  }

  return (
    <div className="queue-item">
      <h3>{currentItem.title}</h3>
      <button onClick={handleProcess}>处理当前项</button>
    </div>
  );
}

关键说明

  • setQueryData 接收一个函数,参数为旧缓存数据,返回新缓存数据,避免直接修改原缓存引发的问题。
  • 针对你的 QueryReturnQueue 类型(数组或 false),添加了类型判断,确保操作安全。
  • 乐观更新为可选配置:如果希望用户操作后立即看到队列推进效果,可启用该逻辑,服务器请求失败时自动回滚缓存。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 02:10:31