为啥我的 Apollo 缓存更新没有反映在我的查询中?

Posted

技术标签:

【中文标题】为啥我的 Apollo 缓存更新没有反映在我的查询中?【英文标题】:Why are my Apollo cache updates not reflected in my queries?为什么我的 Apollo 缓存更新没有反映在我的查询中? 【发布时间】:2020-01-22 04:08:38 【问题描述】:

我正在尝试使用 Apollo 缓存进行本地状态管理来存储表单的状态,以便无需清除即可返回。

我遇到了一个问题,即缓存正在更新,但对缓存的后续查询返回的是陈旧数据。我在使用 useQuery 钩子的 React 组件以及 Apollo DevTools 中都遇到过这个问题,我将在下面演示它:

我的解析器中有这个突变和查询集(我正在使用 Typescript):

const resolvers = 
  Mutation: 
    storeLetterDraft: (_root, args:  type: string, details: LetterSending ,  client, getCacheKey ) => 
      const id = getCacheKey(
        __typename: "LetterDraft",
        id: args.type,
      );

      const data =  ...args.details ;

      client.writeFragment(
        data,
        id,
        fragment: LETTER_SENDING_FRAGMENT,
      );
    ,
  ,
  Query: 
    letterDraft: (_root, args:  type: string ,  client, getCacheKey ) => 
      // I HAVE TRIED A DEBUGGER STATEMENT HERE
      const id = getCacheKey(
        __typename: "LetterDraft",
        id: args.type,
      );

      return client.readFragment(
        id,
        fragment: LETTER_SENDING_FRAGMENT,
      );
    ,
  ,

我的片段是:

export const LETTER_SENDING_FRAGMENT = gql`
  fragment DraftLetterSending on LetterDraft 
    date
    firstName
    lastName
    addressLine1
    addressLine2
    addressTown
    addressCounty
    addressPostcode
  
`;

我正在初始化我的缓存:

cache.writeData(
  data: 
    letterDrafts: [
      __typename: "LetterDraft",
      id: "CREATE",
      addressCounty: "Northamptonshire",
      addressLine1: "1 Watkin Terrace",
      addressLine2: "",
      addressPostcode: "NN1 3ER",
      addressTown: "Northampton",
      date: "2019-11-01",
      firstName: "d",
      lastName: "d",
    ],
  ,
);

我的突变看起来像:

export const storeCreateLetterSendingMutation = gql`
  mutation StoreCreateLetterSending($details: LetterSending!) 
    storeLetterDraft(type: "CREATE", details: $details) @client
  
`;

突变前,Apollo DevTools 中的缓存看起来和预期一样:

查询按预期返回:

执行变异后,缓存更新:

但是,再次运行查询会导致数据过时:

有趣的是,如果我在上面的部分 (I HAVE TRIED A DEBUGGER STATEMENT HERE) 中放置了一个调试器语句,那么查询解析器似乎是第一次运行,但不是第二次运行,所以看起来查询正在被缓存——即使它是我正在更新的缓存!因此,我认为问题在于查询随后没有运行解析器。

【问题讨论】:

【参考方案1】:

我在文档中错过了这一点(Apollo 网站上有很多地方详细介绍了本地缓存和@client。

https://www.apollographql.com/docs/react/essentials/local-state/#forcing-resolvers-with-clientalways-true

虽然在很多情况下利用缓存来获取本地和远程结果都非常有用,但它并不总是最合适的。我们可能希望使用本地解析器来计算需要在每个请求上刷新的动态值,同时继续将缓存用于我们查询的基于网络的部分。为了支持这个用例,Apollo 客户端的 @client 指令接受一个 always 参数,当设置为 true 时,将确保关联的本地解析器在每个请求上运行。

【讨论】:

以上是关于为啥我的 Apollo 缓存更新没有反映在我的查询中?的主要内容,如果未能解决你的问题,请参考以下文章

范围变量值的变化没有反映在我的字符串中

React Apollo:添加新项目时更新列表缓存(带变量)

GraphQL + Apollo - 如何强制进行查询,似乎正在缓存一些东西

React Apollo 在突变后更新客户端缓存

Apollo 查询从缓存中获取了错误的数据

Vue-apollo 从另一个组件重新获取查询