Reputation: 3758
I'm learning ReactJS, Express and socket.io by making a small application where users can join rooms, and interact with each other inside the room (content NYI). Currently, the idea is to have a RoomList view, and an individual Room view. The number of current users in a room should be visible in the RoomList (Room 1: 2 users
, for example).
My router config looks like this:
<Router history={hashHistory}>
<Route path="/" component={App}>
<Route path="rooms" component={RoomList}></Route>
<Route path="rooms/:roomId" component={Room}></Route>
</Route>
</Router>
And the App component:
export default React.createClass({
componentDidMount() {
var socket = io.connect('/')
socket.on('connect', function(data) {
socket.emit('message', "Dududu")
socket.on('message', function(data) {
console.log("Message:", data);
})
})
},
render() {
return (
<div>
{this.props.children}
</div>
)
}
})
The problem is, how can I access the socket instance created here in another component? For example, I'd like to add socket events for joining/leaving a room and other room-specific events in the Room component, updating the RoomList's user count in the RoomList component etc. How can I share the socket object globally, or what is the recommended practice for dealing with sockets and multiple components?
Upvotes: 4
Views: 3979
Reputation: 139
Another solution that I just did on my chat app where I could send realtime communication without any rendering.
I just used uuid
in the parent components state to create an id that I could pass from the parent to context then access in any child component. At that point I just created a room between whatever components that I wanted to share info with and named it using that uuid
.
The reason I went this route rather than Fissio's is because I didn't want to store that huge socket in state.
Now you can have multiple users who each have a unique socket just for them!
Upvotes: 1
Reputation: 3758
Found out what to do through vigorous googling and github issue searching, in the App component do this.setState({socket: socket})
and then for the view, use React.cloneElement
, passing the socket as a prop. Then you can access the socket from child components through this.props.socket
.
export default React.createClass({
componentWillMount() {
var socket = io.connect('/');
this.setState({socket: socket});
},
render() {
return (
<div>
{
React.cloneElement(this.props.children, {socket: this.state.socket})
}
</div>
)
}
})
Upvotes: 3