阿波罗js订阅乐观UI



使用带有订阅的乐观 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,并且存在任何类型的延迟,则在服务器发送响应之前不会显示结果。这可能是一个问题,例如在聊天应用中,如果用户在单击发送按钮后没有看到他们的消息。他们会继续点击按钮并多次发送消息:/

为了在使用优化 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. 或者,您可以将服务器上的订阅限制为不向新频道的创建者发出。

最新更新