实现聊天“历史记录”的正确方法是什么,例如中继连接的分页?

时间:2016-08-18 15:21:46

标签: reactjs relayjs

我正在尝试与中继和订阅进行示例聊天。 我已经设法以某种方式使它工作。 问题是当通过突变或订阅添加新消息时,从视图中推送较旧的消息。但这不是我们期望从聊天中获得的实际行为。当新消息添加到底部时,我们希望所有从历史记录加载的消息都保留在列表中。

playground example(without subscription, but mutation is enough)

with subscriptions

所以我们有:

    查看器上的
  • msgs 字段,即 Msg 连接。
  • AddMsg 变种,它将新消息添加到底部(rangeBehaviors:'append')
  • 中继容器上的
  • $ last 变量,在“再加一个”时增加,使历史记录功能以某种方式工作。

我们可以从容器中增加 $ last ,但我不知道在存储中添加新连接节点时增加它。

我们与同事一起考虑过一些变通办法:

  1. AddMsg 变异回调中的最后一次增量。它适用于变异,但不适用于订阅。而最老的信息仍将通过乐观的反应推出,然后在回复后再次加回。
  2. 尝试在componentWillReceiveProps中增加 $ last 。这似乎是非常hacky的解决方案,因为:

    • 没有办法安全地决定如何处理 $ last ,只知道上一个和下一个道具。
    • componentWillReceiveProps将被多次调用以进行变异(乐观响应,比 $ last 更改,而不是实际响应)
  3. 请勿使用 $ last 变量。相反,如果 last 足够大,则获取msgs(最后:100000000)并使服务器返回第一个响应的默认计数(示例中为2)。在这种情况下,所有都将按预期工作。但后端实际上将无法遵守relay-graphql连接规范。

  4. MsgsContainer viewer 片段拆分为2个(或更多)片段:

    • 历史“...... msgs(最后:$ last,之前:$ lastMsgCursor){...”
    • newMessages“...... msgs(之后:$ lastMsgCursor){...”

    这里的问题是$ lastMsgCursor的消息将从history和newMessages片段中排除,因此我们可能需要第三个片段:lastMessage。但是,如何查询呢?

  5. 这些想法似乎都不是一个好方法。所以我想知道,将历史作为分页工作的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

一种常见的模式是为新项目“腾出空间”,执行变异,并在突变失败的情况下回滚房间:

addMsg() {
  // Make room for the new item.
  this.props.relay.setVariables({ 
    last: this.props.relay.variables.last + 1,
  });
  // Perform the mutation.
  this.props.relay.commitUpdate(
    new AddMsgMutation({ 
      text: "new msg", 
      viewer: this.props.viewer,
    }),
    {
      onFailure: () => {
        // Roll back the room if the mutation fails.
        this.props.relay.setVariables({ 
          last: this.props.relay.variables.last - 1,
        });
      },
    },
  );
}

更新了游乐场:(link