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

useMutation未更新useQuery数据(Tanstack Query)问题排查

问题分析与解决

核心错误:Query数据结构不匹配

你的useQuery返回的data是包含products数组的对象(类型FetchResponse<'products'>),但在useMutation的onSuccess里,你错误地把旧数据当成了纯数组来处理:

// 错误:oldProducts实际是FetchResponse<'products'>类型,不是数组
queryClient.setQueryData<StringRecord[]>(
  ['products'],
  (oldProducts = []) => {
    return [...oldProducts, data];
  },
);

这种修改会让['products']对应的缓存数据结构从对象变成数组,和useQuery期望的类型完全不符,导致useQuery无法识别缓存更新,自然不会触发useEffect。

正确的修改方式

调整setQueryData的逻辑,严格保持和useQuery返回的数据结构一致:

queryClient.setQueryData<FetchResponse<'products'>>(
  ['products'],
  (oldData) => {
    // 保留原有结构,仅追加新产品到products数组
    return {
      ...oldData,
      products: [...(oldData?.products || []), data]
    };
  },
);

额外优化:移除不必要的本地状态

你当前用useEffect把data.products同步到本地状态setProducts,其实完全可以直接使用useQuery返回的data?.products渲染,不需要额外维护本地状态,能彻底避免状态不同步的问题:

// ProductsPage.tsx 可简化为:
const { data, isError, isPending, error } = useQuery<
  FetchResponse<'products'>,
  Error
>({ queryKey: ['products'], queryFn: fetchProductsMock });

// 直接用 data?.products 渲染即可,无需 useEffect 和 setProducts

验证效果

修改后,useMutation成功更新缓存时,useQuery会感知到缓存变化并更新data,此时useEffect(如果保留)会正常触发,控制台能看到useEffect data的输出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 03:17:48