Apollo 客户端 writeQuery 更新存储,但 UI 组件仅在第二次函数调用后更新

Posted

技术标签:

【中文标题】Apollo 客户端 writeQuery 更新存储,但 UI 组件仅在第二次函数调用后更新【英文标题】:Apollo client writeQuery updates stores, but UI componens only updates after the second function call 【发布时间】:2019-11-14 15:41:24 【问题描述】:
"apollo-cache-inmemory": "^1.6.2",
"apollo-client": "^2.6.3",

我使用 client.subscribe 方法设置了一个简单的订阅,并尝试使用 client.writeQuery 方法更新商店

export default class App extends Component<Props> 
  componentDidMount() 
    this.purchaseSubscription = client.subscribe(
      query: PURCHASE_ASSIGNED_SUBSCRIPTION,
      variables:  status: ['INPREPARATION', 'PROCESSED', 'READYFORCOLLECTION', 'ONTHEWAY', 'ATLOCATION'] ,
    ).subscribe(
      next: (subscriptionData) => 
        const  cache  = client;
        const prev = cache.readQuery(
          query: MY_PURCHASES,
          variables:  status: ['INPREPARATION', 'PROCESSED', 'READYFORCOLLECTION', 'ONTHEWAY', 'ATLOCATION'] ,
         );
        const newPurchase = subscriptionData.data.purchaseAssignedToMe;
        const data =  myPurchases: [...prev.myPurchases, newPurchase] ;

        cache.writeQuery(
          query: MY_PURCHASES,
          variables:  status: ['INPREPARATION', 'PROCESSED', 'READYFORCOLLECTION', 'ONTHEWAY', 'ATLOCATION'] ,
          data,
        );
      ,
      error: (err) =>  console.error('err', err) ,
    );
  

  render() 
    return (
      <ApolloProvider client=client>
        <AppContainer />
      </ApolloProvider>
    );
  

商店在调用后更新,但 UI 组件仅在第二个发布事件时重新呈现。

UI 组件的设置方式如下:

  <Query
    query=MY_PURCHASES
    variables= status: ['INPREPARATION', 'PROCESSED', 'READYFORCOLLECTION', 'ONTHEWAY', 'ATLOCATION'] 
    >
   ...
  <Query />

通过在调用 writeQuery 后读取缓存,我能够验证存储是否反映了正确的状态,但是 UI 组件只会在第二次调用时更新。

我在这里错过了什么?

【问题讨论】:

【参考方案1】:

ApolloClient.subscribe 的 next 函数与 Apollo Client 的 mutate 函数中 updateQueries 的工作方式非常相似,但cache.writeQuery 不会在未从 Mutation 的 update 函数中调用时广播更改。

解决方案:使用client.writeQuery(...) 而不是cache.writeQuery(...)

注意:更新函数接收缓存而不是客户端作为它的 第一个参数。这个缓存通常是 InMemoryCache 的一个实例, 当客户端运行时提供给 ApolloClient 构造函数 创建的。在更新功能的情况下,当您调用 cache.writeQuery,更新内部调用了broadcastQueries,所以 侦听更改的查询将更新。 但是,这种行为 cache.writeQuery 之后的广播更改仅发生在 更新功能。在其他任何地方,cache.writeQuery 只会写入 缓存,并且更改不会立即广播到 视图层。为了避免这种混淆,当 写入缓存。

来源:https://www.apollographql.com/docs/react/essentials/mutations/#updating-the-cache

【讨论】:

老兄,我花了好几个小时搞清楚这个问题。非常感谢。

以上是关于Apollo 客户端 writeQuery 更新存储,但 UI 组件仅在第二次函数调用后更新的主要内容,如果未能解决你的问题,请参考以下文章

Apollo 客户端 writeQuery 更新存储,但 UI 组件仅在第二次函数调用后更新

在 Apollo-client 中,writeQuery 会更新缓存,但 UI 组件不会重新渲染

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

变异后的Apollo缓存未更新

轮询不工作时更新 Apollo 客户端 3 的缓存

Apollo 客户端:cache.modify 不起作用?