【问题标题】:Apollo GraphQL client: how to distinguish an optimistic response from a real response into a watchQueryApollo GraphQL 客户端:如何区分对 watchQuery 的乐观响应和真实响应
【发布时间】:2018-10-26 03:57:14
【问题描述】:

问题是关于突变、乐观响应和 watchQuery 的交互。

我有一个突变“myMutation”,它有一个“optimisticResponse”和一个实现的“update”函数。

每次我进行突变查询时,都会调用两次“更新”函数,第一次使用乐观响应数据,第二次使用真实数据。一切正常,如文档中所述。

在我的“更新”函数中,我通过使用 readQuery/writeQuery 方法修改“myQuery”缓存数据。

每次我修改“myQuery”缓存数据时,都会调用一个 watchQuery(基于“myQuery”)订阅。一切正常,如文档中所述。

但问题是我无法在 watchQuery 中区分我收到的是乐观响应数据还是真实响应数据。这对我来说至关重要,因为反应必须不同,因为有价值的数据部分只能由服务器提供。 当我收到一个乐观的响应时,我应该显示一个具有特殊样式的 GUI 元素,并且我应该禁止与它进行任何交互,直到我收到真正的响应。

很遗憾,我无法解决这个问题。乍一看,乐观的反应和真实的反应没有区别。我用谷歌搜索了很多,但没有找到解决方案。我唯一的想法是在我的 GraphQL 数据中添加一个特殊字段,该字段将显示是否从服务器接收到响应。但它看起来很丑,闻起来很臭。我敢肯定,一定有一个简单正确的方法来解决这个问题。

【问题讨论】:

    标签: apollo graphql-js apollo-client


    【解决方案1】:

    也许有更简单的方法,或者将来会有,但这是我所知道的。

    optimisticResponse 中的数据仅在第一次调用更新期间提供。您可以在此处向更新函数标记它正在处理乐观数据。你可以把你想要的任何数据放在那里。我把isOptimistic: true,.

    为了处理watchQuery 问题,我建议您使用apollo-link-state 将一个或多个仅限客户端的字段添加到您的数据模型中应该显示乐观向上插入的区域。不要在你的突变查询中包含isOptimistic,这样你就知道它来自服务器而不是乐观的响应,如果它不是真的,就强制它为假。看这个例子:

    const SUBMIT_COMMENT_MUTATION = gql`
      mutation submitComment($repoFullName: String!, $commentContent: String!) {
        submitComment(repoFullName: $repoFullName, commentContent: $commentContent) {
          postedBy {
            login
            html_url
          }
          createdAt
          content
        }
      }
    `;
    
    const CommentsPageWithMutations = ({ currentUser }) => (
      <Mutation mutation={SUBMIT_COMMENT_MUTATION}>
        {(mutate) => (
          <CommentsPage
            submit={(repoFullName, commentContent) =>
              mutate({
                variables: { repoFullName, commentContent },
                optimisticResponse: {
                  __typename: 'Mutation',
                  submitComment: {
                    __typename: 'Comment',
                    postedBy: currentUser,
                    createdAt: new Date(),
                    content: commentContent,
                    isOptimistic: true, // Only provided to update on the optimistic call
                  },
                },
                update: (proxy, { data: { submitComment } }) => {
                  // Make sure CommentAppQuery includes isOptimistic for each comment added by apollo-link-state
                  // submitComment.isOptimistic will be undefined here if it's from the server
                  const newComment = {
                    ...submitComment,
                    isOptimistic: submitCommit.isOptimistic ? true : false,
                  };
    
                  // Read the data from our cache for this query.
                  const data = proxy.readQuery({ query: CommentAppQuery });
    
                  // Add our comment from the mutation to the end.
                  data.comments.push(newComment);
    
                  // Write our data back to the cache.
                  proxy.writeQuery({ query: CommentAppQuery, data });
                },
              })
            }
          />
        )}
      </Mutation>
    );
    
    

    https://www.apollographql.com/docs/link/links/state.html

    【讨论】:

    • 非常感谢!这正是我所需要的。
    • 不幸的是,出现了另一个问题。然后我使用 apollo-link-state 突变和 watchQuery 正常工作。但是,如果订阅中也存在仅限客户端的字段,它会在收到第一个响应后突然停止。我使用默认值:对不起,我不明白为什么代码块不起作用。 const defaultState = { _loadingStatus: 'READY' }; const stateLink = withClientState({ 缓存,默认值:defaultState,解析器:{} }); 我改变了我的乐观反应。
    • @Dolios 我看不到您的问题有很多问题。但是,您说它在将仅限客户端字段添加到订阅后停止工作。您是否可以尝试不在订阅中包含它,然后从订阅逻辑中的缓存中读取该值?这可能是链接状态的订阅逻辑中的错误。我不知道。
    • 感谢您的回复。它看起来像apollo-link-state 中的一个错误。我在这个问题上创建了一个问题:github.com/apollographql/apollo-link-state/issues/249
    猜你喜欢
    • 2017-04-02
    • 2018-08-17
    • 2018-02-14
    • 2018-09-16
    • 2020-06-14
    • 2019-07-26
    • 2019-06-19
    • 2021-11-11
    • 2020-09-02
    相关资源
    最近更新 更多