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

如何让Apollo Client在mutation后重新获取所有alertsPage查询?

解决Apollo Client Mutation后重新获取所有参数变体的查询

方法1:函数式refetchQueries获取所有查询缓存变体

当你给refetchQueries传查询名称字符串时,Apollo Client只会重新获取最近执行的该名称查询实例。要覆盖所有参数变体的查询,改用函数形式,手动从缓存中提取所有alertsPage的查询记录:

export function useCloseAlert() {
  const client = useApolloClient();
  return useMutation(closeAlertDocument, {
    refetchQueries: async () => {
      // 筛选缓存中所有属于alertsPage查询的键
      const alertQueryKeys = Object.keys(client.cache.data.data).filter(key => 
        key.startsWith('Query.alertsPage(')
      );
      
      // 将每个缓存键转换为包含变量的查询对象
      return alertQueryKeys.map(key => {
        // 解析缓存键中的变量参数
        const variables = JSON.parse(key.split('(')[1].slice(0, -1));
        return {
          query: alertsPageDocument,
          variables,
        };
      });
    },
  });
}

方法2:直接更新缓存替代重新请求

如果不想发起额外网络请求,可以在update函数中手动修改缓存里的统计数据,比如关闭告警后调整OPEN/CLOSED的计数:

export function useCloseAlert() {
  const client = useApolloClient();
  return useMutation(closeAlertDocument, {
    update(cache, { data }) {
      if (!data?.closeAlert) return;
      
      // 遍历所有alertsPage查询缓存
      const alertQueryKeys = Object.keys(cache.data.data).filter(key => 
        key.startsWith('Query.alertsPage(')
      );
      
      alertQueryKeys.forEach(key => {
        const variables = JSON.parse(key.split('(')[1].slice(0, -1));
        const existingData = cache.readQuery({ query: alertsPageDocument, variables });
        
        if (existingData?.alerts?.counts) {
          // 更新计数:OPEN减1,CLOSED加1
          const updatedCounts = existingData.alerts.counts.map(count => {
            switch(count.status) {
              case 'OPEN':
                return { ...count, count: count.count - 1 };
              case 'CLOSED':
                return { ...count, count: count.count + 1 };
              default:
                return count;
            }
          });
          
          // 写回缓存
          cache.writeQuery({
            query: alertsPageDocument,
            variables,
            data: {
              ...existingData,
              alerts: { ...existingData.alerts, counts: updatedCounts }
            }
          });
        }
      });
    },
  });
}

方法3:重新获取活跃的查询实例(Apollo Client 3+)

如果只需要重新获取当前活跃的(比如页面正在监听的)alertsPage查询,可以通过查询管理器获取:

export function useCloseAlert() {
  const client = useApolloClient();
  return useMutation(closeAlertDocument, {
    refetchQueries: () => {
      // 筛选所有活跃的alertsPage查询
      return client.queryManager.getObservableQueries()
        .filter(query => query.options.query.definitions[0].name.value === 'alertsPage')
        .map(query => ({
          query: query.options.query,
          variables: query.options.variables
        }));
    },
  });
}

各方法对比

  • 方法1:重新发起所有查询,数据绝对最新,但会增加网络请求量。
  • 方法2:无网络开销,性能更好,但需要手动维护缓存更新逻辑,适合简单数据变更场景。
  • 方法3:仅更新活跃查询,适合不需要同步历史缓存的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 04:02:45