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

useMemo依赖Apollo useQuery返回的data变更时未触发执行问题排查

问题根本原因

  • Apollo Client 的 useQuery 返回的 data 是全局共享缓存数据的直接引用,没有做额外拷贝,以此降低性能开销。
  • 你在第一个标签页的 useMemo 逻辑里直接修改了 data 对象,相当于直接篡改了 Apollo 全局缓存中的存储值。
  • 第二个标签页的组件请求新数据时,若 Apollo 对比新返回的接口数据与缓存中已被篡改的数据后,判断无需更新引用,就会返回和上一次渲染完全相同的 data 引用。
  • 原生 useMemo 对依赖项做的是浅比较,只要引用地址不变,哪怕对象内部属性已经发生变化,也不会重新执行内部逻辑。

修复方案

  1. 禁止直接修改 useQuery 返回的 data 原对象
    所有对 data 的修改都要基于副本操作,不要改动原对象:
const result = useMemo(() => {
  // 浅结构用扩展运算符拷贝,深层结构可以用 structuredClone 或业务适配的深拷贝逻辑
  const dataCopy = {...data};
  // 所有修改操作都针对 dataCopy 执行
  // 你的业务逻辑
}, [data])
  1. 调整 useQuery 配置强制返回新对象引用
    如果需要规避缓存复用的问题,可以给 useQuery 配置独立的请求策略,确保每次请求返回新的对象引用:
const { data, loading, error: loadRolesError } = useQuery(你的查询语句, {
  fetchPolicy: 'network-only',
  nextFetchPolicy: 'network-only'
});
  1. 拆分 useMemo 依赖项
    如果业务需要感知 data 内部特定属性的变化,可以把关键属性提取出来作为依赖,代替直接用整个 data 对象:
const result = useMemo(() => {
  // 业务逻辑
}, [data?.id, data?.列表字段?.length, loading])
  1. 使用深比较的自定义缓存Hook
    如果必须监听对象所有深层属性的变化,可以自行实现基于深比较的 useDeepMemo 代替原生 useMemo,注意评估深比较带来的性能开销。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 13:30:02