Apollo 客户端中的乐观响应与更新?

Posted

技术标签:

【中文标题】Apollo 客户端中的乐观响应与更新?【英文标题】:optimisticResponse vs update in Apollo Client? 【发布时间】:2018-08-17 14:21:15 【问题描述】:

我想在突变后使用乐观的 UI 更新:https://www.apollographql.com/docs/react/basics/mutations.html

我对“optimisticResponse”和“update”之间的关系感到困惑。

这里使用了optimisticResponse:

    const CommentPageWithData = graphql(submitComment, 
      props: ( ownProps, mutate ) => (
        submit: ( repoFullName, commentContent ) => mutate(
          variables:  repoFullName, commentContent ,

          optimisticResponse: 
            __typename: 'Mutation',
            submitComment: 
              __typename: 'Comment',
              // Note that we can access the props of the container at `ownProps` if we
              // need that information to compute the optimistic response
              postedBy: ownProps.currentUser,
              createdAt: +new Date,
              content: commentContent,
            ,
          ,
        ),
      ),
    )(CommentPage);

仅使用此更新商店吗?

然后文档说这是用来更新缓存的:

    const text = 'Hello, world!';

    client.mutate(
      mutation: TodoCreateMutation,
      variables: 
        text,
      ,
      update: (proxy,  data:  createTodo  ) => 
        // Read the data from our cache for this query.
        const data = proxy.readQuery( query: TodoAppQuery );

        // Add our todo from the mutation to the end.
        data.todos.push(createTodo);

        // Write our data back to the cache.
        proxy.writeQuery( query: TodoAppQuery, data );
      ,
    );

这是我在不使用optimisticResponse 函数的情况下成功更新UI 的方法。

两者有什么区别?你应该使用两者还是只使用一个?

【问题讨论】:

【参考方案1】:

为了扩展其他两个答案,区别在于您正在“更新”的内容是否已经存在于缓存中。

根据docs,如果您要更新现有项目,比如编辑待办事项的标题,您只需要optimisticResponse。为什么?因为缓存中包含节点,你只需要告诉它新节点发生了一些新的事情,这会立即反映在 UI 上。

optimisticResponse 只是提供来自突变的“即时”结果数据。

现在我们有第二种情况,您想在列表中添加一个新的 Todo 项目。首先,缓存需要知道创建了一个新项目。只要您向 Mutation 提供 update 属性,您就可以控制缓存的状态。

update 取代了refetchQueries,这意味着您可以控制缓存状态

使用update,您可以访问缓存并专门修改/附加您需要的节点,而不是重新获取整个数据层次结构。但是,您仍在等待 Mutation 完成。如果您在optimisticResponse 旁边提供update,则您将提供一个即时假定响应,并将其提供给您的个人update 函数,然后该函数会立即更新缓存。

这两个在方案二中配对的原因是您完全绕过了服务器响应。如果你只是给出一个“立即”响应,Apollo 仍然处于等待服务器更新缓存的模式。 update 也可以让你劫持它,并在客户端进行。

最后说明:您假设服务器始终响应且没有错误。其他地方的错误处理仍然有效,但如果您经常捕获错误(例如isLoggedIn 场景),您可能会遇到 UI 不一致,因此请确保您“快速跟踪”的查询通常是健康的。

【讨论】:

【参考方案2】:

他们做不同的事情。 optimisticResponse 预测来自服务器的响应。如果您要更新商店中已有的节点,那么这可能就是您所需要的。

更新功能让您可以完全控制您的商店。例如,如果您创建了一个新节点,则需要将其添加到相关查询中。作为一个新实体,Apollo 不会自动知道如何处理它。

【讨论】:

【参考方案3】:

用于修改存储的乐观响应,无需来自后端的响应。商店在收到新数据时自行更新

用于使用来自后端的响应修改存储的更新。商店不会自行更新

【讨论】:

以上是关于Apollo 客户端中的乐观响应与更新?的主要内容,如果未能解决你的问题,请参考以下文章

Apollo 客户端:在创建过程中进行乐观更新

Apollo GraphQL 乐观响应和更新商店问题

Apollo 客户端递归突变

使用突变响应更新 apollo 客户端

在 Apollo v3 React 客户端 fe-retching 不同查询的情况下如何实现乐观 UI

使用 writeQuery() 更新 Apollo 客户端上的缓存