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

Apollo client writeQuery updates stores, but UI componens only updates after the second function call

"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 组件仅在每次调用时更新一次。

我在这里错过了什么?

ApolloClient.subscribe 的 next 函数与 updateQueries 在 Apollo Client 的 mutate 函数中的工作方式非常相似,但不同的是 cache.writeQuery 如果不是从Mutation的更新函数。

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

Note: The update function receives cache rather than client as its first parameter. This cache is typically an instance of InMemoryCache, as supplied to the ApolloClient constructor when the client was created. In case of the update function, when you call cache.writeQuery, the update internally calls broadcastQueries, so queries listening to the changes will update. However, this behavior of broadcasting changes after cache.writeQuery happens only with the update function. Anywhere else, cache.writeQuery would just write to the cache, and the changes would not be immediately broadcast to the view layer. To avoid this confusion, prefer client.writeQuery when writing to cache.

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