我正在写一个非常简单的Nodejs应用程序。我使用React + Socket.io。
有一个根元素,它立即渲染另一个react组件(你可能想知道为什么我有这个根元素。原因是我希望能够在从服务器接收消息后挂载两个组件中的一个,但首先我呈现了一个预选的组件)。在这个根组件中,我在componentDidMount
中定义一个套接字。现在的问题是,我想把这个套接字传递给所有的子进程(这样它们就可以监听并与服务器消息通信)。但是如果我连接到根的componentDidMount
中的服务器,在渲染期间没有套接字,因为它还没有连接,null
将传递给子组件。
'use strict';
var React = require('react');
var ioClient = require('socket.io-client');
var UsersList = require('./usersList');
var Game = require('./game');
var socket;
var Snake = React.createClass({
displayName: 'Snake',
propTypes: {},
getDefaultProps: function() {
return {};
},
mixins: [],
getInitialState: function() {
return ({
usersList: true,
game: false
});
},
componentWillMount: function() {
},
componentWillUnmount: function() {
this.socket.close();
},
componentDidMount: function() {
socket = ioClient.connect(); // this happens after render
},
render: function() {
var result = null;
if (this.state.usersList) {
result = <UsersList socket={socket}/> // therefore this one is passed as null
} else { //game : true
result = <Game socket={socket}/>
}
return (<div>
{result}
</div>)
}
});
module.exports = Snake;
'use strict';
var React = require('react');
var UsersList = React.createClass({
displayName: 'UsersList',
propTypes: {},
getDefaultProps: function() {
return {};
},
mixins: [],
getInitialState: function() {
return ({
usersList:[]
});
},
componentWillReceiveProps: function(){
},
componentWillMount: function() {
},
componentWillUnmount: function() {
},
componentDidMount: function(){
var socket = this.props.socket; // this one was passed into the component as null
socket.on('usersList', function(data){ // so this one returns an error
this.setState({
usersList: data.usersList
});
});
},
render: function() {
var users = [];
for (var i = 0 ; i < this.state.usersList.length ; i++){
users.push(<span>{this.state.usersList[i]}</span>);
}
return(<div>{users}</div>);
}
});
module.exports = UsersList;
所以,现在你可能会问为什么我不把io.connect()
放在componentWillMount
或在文件的顶部。好吧,它不起作用!它返回这个错误:Cannot find property "protocol" ...
。我不能把它放在render
, componentWillMount
,文件的顶部…
你知道怎么做吗?
您可以在componentDidMount
中继续连接。它不会立即对组件的子组件可用,但随后您可以在子组件中执行以下操作:
componentDidUpdate(prevProps, prevState) {
if ( this.props.socket ) {
// do your connection logic here
}
}
这将确保当套接字第一次连接并对它们可用时,子进程立即连接。在if
语句中,您还可以验证this.props.socket
不等于prevProps.socket
,以防止多余的连接尝试。