reactjs - Apollo js 订阅乐观 UI

标签 reactjs apollo subscriptions optimistic-ui

使用 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 对订阅有意义吗?

最佳答案

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

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

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

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

  1. 检查客户端上是否存在欺骗行为:

    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],
          },
        });
      },
    
  2. 或者您可以限制服务器上的订阅,使其不发送给新 channel 的创建者。

关于reactjs - Apollo js 订阅乐观 UI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44051690/

相关文章:

javascript - 无法在 'readAsBinaryString' : parameter 1 is not of type 'FileReader' 上执行 'Blob'

reactjs - 使用apollo,响应头中的cookie但未设置

reactjs - 如何更新 useSubscription Hook 中的订阅变量 - Apollo v3

添加后立即支付宝订阅 "expires"

php - 更改 Stripe 中具有多个订阅项的订阅的订阅间隔

javascript - 如何在图像 ex : <img src ='returnedString' />? 的源标记中使用返回的字符串(React v16.0.0 的新功能)

javascript - 由子路由和在其之上渲染的页面驱动的react-router基础组件

javascript - 如何在 Html/Css 和 React js 中实现这个 slider ?

javascript - 在 Meteor 中访问订阅时出现问题

apollo - 将数据从客户端添加到 Apollo?