Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ReactJS, react-router and socket.io

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?

like image 731
Fissio Avatar asked Oct 31 '25 02:10

Fissio


1 Answers

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>
    )
  }
})
like image 118
Fissio Avatar answered Nov 01 '25 18:11

Fissio



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!