I'm trying to work with react as a client and nodejs and soket io as a server.

On my react app, when a user submit the form, I want to emit a socket io event with the form data but I don't seem to be catching the event on the server.

Here is my code, the thing is I don't get any error, I assume i'm missing something but can't figure out what is it.

App.js

First I'm passing my io object to my routes, I don't know if doing so is a good practice, I just want to avoid redefine the connection in every components.

import React, { Component } from 'react';
import './App.css';
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
import Home from './Route/Home';
import Game from './Route/Game';
import io from 'socket.io-client';

class App extends Component {

  constructor(props){
    super(props);
    this.state = {
      io: io('http://localhost:5000'),
    };
  }

  render() {
    return (
      <Router>
          <Switch>
              <Route exact path='/'>
                <Home io={this.state.io} />
              </Route>
              <Route path='/game' component={Game} io={this.state.io}>
                <Game/>
              </Route>
          </Switch>
      </Router>
    );
  }
}

export default App;

Home.js

Here I am emiting the event SET_USERNAME with the username state as a parameter.

import React, { Component } from 'react';
import '../css/color.css';
import '../css/home.css';

class Home extends Component {

  constructor(props){
    super(props);
    const { io } = props;
    this.state = {username: '', io : io};
  }

  handleChange = (e) => {
    this.setState({username : e.target.value});
  }

  handleSubmit = (e) => {
    e.preventDefault();
    const { io } = this.state;
    io.emit('SET_USERNAME', this.state.username);
  }

  render() {
    return (
        <section className="background">
          <div className="form_layout">
            <form className="form" onSubmit={this.handleSubmit} >
              <div className="form_label">
                <label htmlFor="">What's your name ?</label>
              </div>
              <input value={this.state.username} onChange={this.handleChange} className="form_input" type="text"/>
              <input className=" form_input form_button" type="submit" value="Submit"/>
            </form>
          </div>
        </section>
    );
  }
}

export default Home;

Here is what appear if I add a console.log(io) right after the emit function. io object

And server.js I expect to get my username's state print in my console, but nothing happend here, seems like the event isn't call.

var user = 0;

io.on('connection', (socket) => {
  user++;
  console.log(user);

  io.on('SET_USERNAME', (username) => {
    console.log(username);
  });

  socket.on('disconnect', () => {
    user--;  
    console.log(user);
  });

});

server.listen(5000, () => {
  console.log('listening on *:5000');
});

Thank you for your help !

1 Answers

1
braza On Best Solutions

I think you've accidentally called io instead of socket to receive the event.

  io.on('SET_USERNAME', (username) => {
    console.log(username);
  });

Should be changed to:

  socket.on('SET_USERNAME', (username) => {
    console.log(username);
  });

In server.js.