React和Socket.io:能够获取初始数据 – 但是当新post进来时视图不会更新

不知道如果问题是如何我的套接字设置 – 或者如果我不正确地尝试使用React呈现数据。

我可以成功地使用套接字获取数据,但是当新数据发布到服务器时,它不会处于更新状态。 我的意图是React中的状态自动呈现新的数据,这是因为套接字连接而始终处于活动状态。

这是我的客户端应用程序从服务器获取消息并呈现它们:

var Chat = React.createClass({ getInitialState: function() { return { messages: null } }, componentWillMount: function(){ var self = this; socket.emit('getMessages'); socket.on('serverMessages', function (data) { self.setState({messages: data}) }); }, render: function() { var messages = this.state.messages ? <MessageList messages={this.state.messages}/> : null return ( <div className="jumbotron"> { messages } <MessageForm submitMessage={this.submitMessage}/> </div> ); } }); 

以防万一这是我的服务器代码发出的数据:

 io.on('connection', function (socket) { socket.on('getMessages', function (data) { Message.find(function(err, messages){ socket.emit('serverMessages', messages); }) }); }); 

尝试这个:

 var Chat = React.createClass({ getInitialState: function() { return { messages: null } }, componentWillMount: function(){ var self = this; socket.emit('getMessages'); socket.on('serverMessages', function (data) { self.setState({messages: data}) }); }, render: function() { var messages = this.state.messages ? <MessageList messages={this.state.messages}/> : null return ( <div className="jumbotron"> { messages } <MessageForm submitMessage={this.submitMessage}/> </div> ); } }); 

就目前而言,一旦组件加载完成,您就只需从服务器获取数据。 为了获得更多的“实时”,你需要使用你定期emit的同样的emit语句来ping服务器(这违背了使用websocket的观点,实际上,你可以使用long-polling)或者定期的向所有客户发送新数据。

你可以做:

A)客户端:“轮询”获取信息[不理想]

注:我最初把这个在我的答案,因为我看到OP是“轮询”时,控制器加载。 我没有点击,这可能是因为控制器可能没有加载WebSocket,所以发送连接数据可能无法在这里工作。 我的错。

socket.emit('getMessages')replace为定期轮询websocket获取数据的内容:

 setInterval(function () { socket.emit('getMessages') }, 10000); /* Request data from the socket every 10 seconds */ 

要么

B)服务器端:发送新的数据,因为它变得可用。 [最好的办法]

通过客户端数组跟踪所有客户端,并在会话结束时将其从客户端数组中删除。

 var clients = []; io.on('connection', function (socket) { clients.push(socket); socket.on('end', function () { // Could also splice the array below, but it still works. delete clients[clients.indexOf(socket)]; }); /* Previous logic for server goes here */ }); 

当您需要从数据库/数据存储中推送新消息时运行此代码:

 for (var i in clients) { clients[i].emit('serverMessages', /* messages object */); } 

您的服务器代码仅在初始套接字connection触发。

服务器:

 socket.on('getMessages', function (data) { Message.find(function(err, messages){ socket.emit('serverMessages', messages); }) }); 

客户:

 var Chat = React.createClass({ getInitialState: function() { return { messages: null } }, componentWillMount: function(){ var self = this; socket.emit('getMessages'); socket.on('serverMessages', function (data) { self.setState({messages: data}) }); }, render: function() { var messages = this.state.messages ? <MessageList messages={this.state.messages}/> : null return ( <div className="jumbotron"> { messages } </div> ); } }); 

基于命名约定,它也显示你的Message.find()正在拉一条消息。 我会build议澄清标签以匹配基数。

它有可能是由于componentWillMount生命周期方法吗? 你可以尝试componentDidMount来代替。

它看起来像渲染将看到状态更新,但只有执行一次,尽pipe根据Facebook的状态改变。