Apollo js 订阅乐观 UI

Posted

技术标签:

【中文标题】Apollo js 订阅乐观 UI【英文标题】:Apollo js Subscriptions Optimistic UI 【发布时间】:2017-10-18 12:00:27 【问题描述】:

使用订阅的 Optimistic UI 有意义吗?

所以基本上:

addChannelMutation(
  variables:  name: eventValue ,
  optimisticResponse: 
    __typename: "Mutation",
    addChannel: 
      __typename: "Channel",
      id: data.channels.length,
      name: eventValue
    
  ,
  update: (store,  data:  addChannel  ) => 
    // Read the data from our cache for this query.
    const data = store.readQuery( query: channelsListQuery );
    // Add our comment from the mutation to the end.
    data.channels.push(addChannel);
    // Write our data back to the cache.
    store.writeQuery( query: channelsListQuery, data );
  
).then(res => );

它添加了两次触发重复键异常的相同项目。 因此,乐观的 ui 对订阅有意义吗?

【问题讨论】:

【参考方案1】:

optimisticResponse 在服务器收到响应之前触发update。然后当服务器响应时,再次触发update,并将乐观占位符替换为响应。

只有在服务器突变解决后,订阅才会发出,因此基本上是在服务器响应时。

如果您没有包含 Optimistic UI 并且存在任何延迟,则在服务器发送响应之前结果不会显示。这可能是一个问题,例如在聊天应用程序中,如果用户在单击发送按钮后没有立即看到他们的消息。他们会不断点击按钮并多次发送消息:/

为了在使用 Optimisic UI 和订阅时打击骗子,两种策略包括:

    检查客户端上的欺骗:

    updateupdateQuery 函数中:

    // super simplified dupe doc checker
    function isDuplicateDocument(newDocument, existingDocuments) 
      return newDocument.id !== null && existingDocuments.some(doc => newDocument.id === doc.id);
    
    
    addChannelMutation(
      variables:  name: eventValue ,
      optimisticResponse: 
        __typename: "Mutation",
        addChannel: 
          __typename: "Channel",
          id: data.channels.length,
          name: eventValue
        
      ,
      update: (store,  data:  addChannel  ) => 
        // Read the data from our cache for this query.
        const data = store.readQuery( query: channelsListQuery );
        if (isDuplicateDocument(addChannel, data.channels) 
          return;
        
    
        // Add our comment from the mutation to the end.
        data.channels.push(addChannel);
        // Write our data back to the cache.
        store.writeQuery( query: channelsListQuery, data );
      
    ).then(res => );
    

    还有在您订阅的updateQuery 内:

    subscribeToMore(
      ...
      updateQuery: (previousResult,  subscriptionData ) => 
        const newChannel = subscriptionData.data.addChannel;
        // if it's our own mutation
        // we might get the subscription result
        // after the mutation result.
        if (isDuplicateDocument(
          newChannel, previousResult.channels)
        ) 
          return previousResult;
        
    
        return update(previousResult, 
          channels: 
            $push: [newChannel],
          ,
        );
      ,
    

    或者您可以限制服务器上的订阅不发送给新频道的创建者。

【讨论】:

谢谢。这正是我正在做的。

以上是关于Apollo js 订阅乐观 UI的主要内容,如果未能解决你的问题,请参考以下文章

Apollo GraphQL 取消订阅似乎坏了

如何立即触发 apollo graphql 订阅?

React Apollo 显示“react-apollo 仅支持每个 HOC 的查询、订阅或突变”错误

Apollo 订阅未在客户端监听新数据

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

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