无需轮询更改的React服务器端渲染

7

我正在尝试将一个现有的基于knockout框架的web应用转换成react js。该应用程序与服务器建立websocket连接并异步接收更新(例如可能有多个客户端,它们之间可以相互影响,比如聊天室)。

我的问题是,如果我要在服务器端进行渲染,如何将更改推送到每个客户端?我只是开始阅读有关服务器端渲染的内容,所以我可能会误解其工作原理,但我认为:

客户端执行操作并将其发送到服务器,服务器响应一个HTML片段,客户端然后将其替换为DOM。

对于一个状态可被服务器或其他客户端更改的应用程序,我是否仍然需要使用websocket / http轮询来显示这些更新?

否则,服务器是否能够推送新的HTML片段?

2个回答

7

在React中,单向数据流通常是最佳实践。为了实现这一点,我们应该使用事件发射器。

您可以通过WebSockets、SSE或轮询从服务器获取JSON(无论哪种方式)。它们应该采用信封格式。以下是聊天应用程序的示例:

{
  "type": "new-message", 
  "payload": {
    "from": "someone",
    "to": "#some-channel",
    "time": 1415844019196
  }
}

当你从服务器收到这条消息时,将其作为事件发出。
var handleMessage = function(envelope){
   myEventEmitter.emit(envelope.type, envelope.payload);
};

这是一种调度器。它只是获取事件,并将其广播给任何感兴趣的人。通常,感兴趣的方可能是组件或存储(在Flux中)。

var MessageList = React.createClass({
   componentDidMount: function(){
      myEventEmitter.on('new-message', this.handleNewMessage);
   },
   handleNewMessage: function(message){
      if (message.to === this.props.channel) {
          this.setState({messages: this.state.messages.concat(message)});
      }
   },
   componentWillUnmount: function(){
      myEventEmitter.removeListener(this.handleNewMessage);
   },
   ...
});

当用户提交消息时,您需要发出一个“user-new-message”事件。实现handleMessage的代码部分也会侦听此事件,将消息发送到服务器,并发出新消息事件,以便更新UI。
您还可以在代码的其他位置(而不是组件中)保留已收到的消息列表,或者请求从服务器获取最近的消息。
通常从服务器发送html是一个非常糟糕、不灵活和性能差的想法。AJAX用于将数据传输到客户端,客户端选择如何向用户呈现这些数据。

阅读有关Flux的资料,这似乎是标准方法,因此在这种情况下,客户端渲染是唯一的选择? - ioseph
Flux是一种方法,有些人使用它,而有些人则不使用。问题是:您在服务器上呈现的原因是什么? - Brigand
我的想法是它可以提高在较慢的机器/设备上的性能,因为应用程序最终会变得非常复杂。 - ioseph
2
ioseph,网络性能比CPU更有价值。这也会使开发变得更慢和更复杂。现在我们所有的东西都是客户端处理,原因是在奇怪的混合模式下运行时会遇到问题。 - Brigand

0
如果我在服务器端进行渲染,如何将更改推送到每个客户端?
好吧,你已经说了,通过Sockets。
然而,这并不是真正的“最佳选择”。您不希望每次都将标记向下传递。如果客户端没有模板,则建议将模板推送到客户端,或者只需在页面中预加载它。当他们这样做时,只需向下传递数据,并由客户端进行呈现。
在应用程序状态可以由服务器或其他客户端更改的情况下,我是否仍然被迫使用WebSockets / http轮询来显示这些更新?
有一种名为Server-Side Events的WebSockets替代方案。它有点像WebSockets,但是它是单向的,只能从服务器->浏览器。浏览器以与通过WebSockets监听服务器端内容相同的方式进行侦听。但是,在与服务器通信时,您可以使用普通的AJAX或表单或任何其他方法。支持有限,但有填充物。
实际上,你可以使用WebSockets来做同样的事情,只需利用下行线路即可,但这将违背其目的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接