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的状态改变。