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

Posted

技术标签:

【中文标题】Apollo 查询从缓存中获取了错误的数据【英文标题】:Apollo query has the wrong data from cache 【发布时间】:2019-07-03 22:10:09 【问题描述】:

Apollo 查询在我的 React 应用程序的缓存中有错误的数据。

如果我将查询的 fetchPolicy 设置为“仅限网络”,则一切正常。

所以我认为是缓存问题。

我一直在努力解决这个问题,看到了关于apollo缓存的文章,但我仍然无法解决问题。

这是我查询后的结果:

参数memberId为空(结果正确)

[
  
    "id": 87,
    "totalQuantity": 12,
    "Orders": [
      
        "id": 1,
        "quantity": 11,
        "Member": 
          "id": 1,
          "name": "A"
        
      ,
      
        "id": 28,
        "quantity": 1,
        "Member": 
          "id": 9,
          "name": "B"
        
      
    ]
  ,
  
    "id": 88,
    "totalQuantity": 1,
    "Orders": [
      
        "id": 2,
        "quantity": 1,
        "Member": 
          "id": 1,
          "name": "A"
        
      
    ]
  
]

参数memberId为9(结果正确)

[
  
    "id": 87,
    "totalQuantity": 1,
    "Orders": [
      
        "id": 28,
        "quantity": 1,
        "Member": 
          "id": 9,
          "name": "B"
        
      
    ]
  
]

参数memberId为1(结果正确)

[
  
    "id": 87,
    "totalQuantity": 11,
    "Orders": [
      
        "id": 1,
        "quantity": 11,
        "Member": 
          "id": 1,
          "name": "A"
        
      
    ]
  ,
  
    "id": 88,
    "totalQuantity": 1,
    "Orders": [
      
        "id": 2,
        "quantity": 1,
        "Member": 
          "id": 1,
          "name": "A"
        
      
    ]
  
]

但是当我返回参数为空时结果是错误的

[
  
    "id": 87,
    "totalQuantity": 11,
    "Orders": [
      
        "id": 1,
        "quantity": 11,
        "Member": 
          "id": 1,
          "name": "A"
        
      
    ]
  ,
  
    "id": 88,
    "totalQuantity": 1,
    "Orders": [
      
        "id": 2,
        "quantity": 1,
        "Member": 
          "id": 1,
          "name": "A"
        
      
    ]
  
]

成员 B (id = 9) 消失了..

而我回参数是9(结果是错误的)

[
  
    "id": 87,
    "totalQuantity": 11,
    "Orders": [
      
        "id": 1,
        "quantity": 11,
        "Member": 
          "id": 1,
          "name": "A"
        
      
    ]
  
]

我得到的是会员 A 的数据,而不是会员 B

有人可以帮助我吗?谢谢


我的客户端配置(缓存是 InMemoryCache)

const client = new ApolloClient(
  link: ApolloLink.from([
    httpLink,
  ]),
  cache,
  dataIdFromObject: o => $o.id$o.__typename,
);

我使用 queryHook 来包装我的组件

const queryHook = graphql(FETCH_ORDER_GROUP_SHIPMENT_LIST, 
  options: ownProps => (
  variables: 
    memberId: ownProps.options.memberId || null,
  ,
),
  props: (
    data: 
      orderGroupShipmentList,
    ,
  ) => (
    orderGroupShipmentList: orderGroupShipmentList || [],
  );

我还使用查询标签(其他数据)来包装我的内容

它的参数也是memberId。

这样的结构

<Query
  variables= memberId: options.memberId || null 
  query=FETCH_MEMBER_LIST_QUERY>
  content that use orderGroupShipmentList and memberList
</Query>

我不知道这是否足够具体

如果这还不够具体,请告诉我

谢谢


2019-09-16

对于那些面临同样问题的人:

https://kamranicus.com/posts/2018-03-06-graphql-apollo-object-caching

【问题讨论】:

请分享代码 查看您的客户端配置以及实际使用您的查询的代码会很有帮助。 如果这些是您从服务器获得的响应,则似乎缺少 __typename,这表明您在客户端配置中有意将 addTypename 设置为 false。是这样吗? @DhavalChheda 已更新,谢谢! @DanielRearden 已更新,谢谢,并且 __typename 存在,我只是忽略了这一点 【参考方案1】:

您需要在查询的返回结果中为该类型提供不同的 ID。例如,基于 memberId 的 id 87 有不同的结果,因此缓存将被您的第二个查询覆盖,并且由于默认情况下 apollo 不会重新获取已经进行的查询,因此它将继续查看覆盖的结果。

【讨论】:

抱歉回复晚了。你说的对!顺便找了一篇文章解释了我的问题:kamranicus.com/posts/2018-03-06-graphql-apollo-object-caching @Anymore:谢谢你的链接。我今天遇到了这个问题,我终于知道为什么了 @HoangTrinh 很高兴能帮到你【参考方案2】:

@Anymore - 我们可以看到您的 FETCH_MEMBER_LIST_QUERY 代码吗?您是否正在获取所有数据的 ID?如果没有 id,它将无法匹配关系。

您是否尝试过使用 Apollo Client DevTools - 它们可以让您轻松查看缓存的内容。可以在 GitHub here 和 Chrome Webstore here 上找到它

使用它,您将能够查看项目是否被正确缓存。

【讨论】:

我确定我获取了所有数据的 id。 我使用Apollo Client DevTools发现当我将参数memberId从9改为1时缓存数据是正确的 但是当我将参数改回 9 时,缓存没有缓存正确的数据(缓存数据保持不变) 我稍后会更新我的问题进行具体解释

以上是关于Apollo 查询从缓存中获取了错误的数据的主要内容,如果未能解决你的问题,请参考以下文章

Apollo readQuery,从缓存中获取数据

从上下文中获取模型与导入 - apollo server express & mongoose

禁用从 apollo-boost 导出的 ApolloClient 中的缓存

查询后如何更新 Apollo 缓存?

apollo-client:如何从缓存中获取反向关系?

Apollo useQuery 钩子不会使用 writeQuery() 方法从缓存中获取更新。没有看到错误