acharotariya
acharotariya

Reputation: 1

socket.on event firing multiple times in react.js

I'm emitting socket event from my sever end point & listen that event on react.js client with socket.on() but i found my socket.on event firing multiple times when emit event.I read many question related this issue on stack overflow but did't succeed.

Here relavant code:

server

 currentUsers: async function (req, res, next) {
      try {
          let io = req.app.get("socketio")  // get socketio instance
          const uoid = req.body.uoid;
          const uuid = req.body.uuid || req.decoded.uuid
          const beacon_name = req.body.beacon_name
          if (uuid !== undefined && beacon_name !== undefined && uoid !== undefined) {
              let find = await knex('current_users').where(knex.raw('uuid = ? and uoid = ?', [uuid, uoid])).catch((err) => { return Promise.reject(err) })
              if (find.length == 0) {
                  let result = await knex('current_users').insert({ uuid: uuid, uoid: req.body.uoid, beacon_name: beacon_name, created_at: helper.currentTimeStamp(), in_at: helper.currentTimeStamp(), in: 1,out: 0 }).catch((err) => { return Promise.reject(err) })
                  console.log('result', result)
                  let getResult = await knex('users').select('users.id', 'users.name', 'users.email','users.mobile_number', 'users.auth_type', 'users.uuid', 'users.role','current_users.beacon_name','current_users.id as ob_id','beacons_info.beacon_room','current_users.in_at','current_users.out_at').innerJoin('current_users', 'users.uuid', '=', 'current_users.uuid').innerJoin('outlets','outlets.id','=','current_users.uoid').innerJoin('beacons_info', 'beacons_info.name', '=', 'current_users.beacon_name').where(knex.raw('current_users.id = ?',result))
                     io.emit('in_users',getResult)
                     res.end()
                 }
          }
    } catch (err) {
         console.log("err =====>", err)
    }
}

client

    import React from "react";
    import socket from "../../../../utils/socket.io"; // get socket
    import EventEmitter from 'events';
    class CurrentUsers extends React.Component {
       _isMounted = false;
       constructor(props) {
          super(props);
          this.outlet_id = sessionStorage.outlet_id ? sessionStorage.outlet_id : "";
          this.selecteId = null;
          this.in_users = [];
          this.state = {
             loading: true,
             data: [],
             editData: {
                name: "",
                date: "",
                room: ""
             }
          };
       }

       componentDidMount() {
          console.log("calling component did mount");
          this._isMounted = true;
          this.setState({ loading: true });
          socket.emit('request-current-users-list',this.outlet_id)
       }


      componentWillUnmount() {
          this._isMounted = false;
       }

      render() {

          socket.on('get-current-users-list',(data)=>{
             this.setState({ data: data,loading: false})
          })
          console.log(EventEmitter.listenerCount(socket, 'in_users'));

          socket.on('in_users', (data) => {
             console.log("=== in ===", data)
          })
        return (
    // template html code
    );
         }
        }

here socket.on(in_users) event firing multiple times.

Upvotes: 0

Views: 2493

Answers (2)

Cloyd Abad
Cloyd Abad

Reputation: 737

Somehow it keeps adding the listener each time the socket.on is fired. I tried this:

socket.off('MY_EVENT').on('MY_EVENT', () => doThisOnlyOnce());

I found it on code grepper, and it worked for me.

EDIT: socket.on is fired on each render. so turning it off and on isn't such an efficient way of doing it. A better way would do it would be to run socket.on on first render.

useEffect(()=>{
    socket.on('MY_EVENT', () => doThisOnlyOnce());
},[])

Upvotes: 3

Abdul Kabeer
Abdul Kabeer

Reputation: 287

Put all of your socketio listerners in React inside componentDidMount ,

Its because re-renders, React re-renders multiple times when ever any state changes ,so basically your socketio listerers just keep adding up. That is why you are getting multiple events fired. You just need to add your socketio listeners once , so add your listeners inside componentDidMount()

Upvotes: 2

Related Questions