title: Socket.io emits the same message more than once on private messages
body: <p>I'm trying to implement private messaging between two users using socket.io, nodejs, and react. I think the private message is being emitted multiple times even though we click send once on user A side, and user B doesn't get the message until we type something on some text box on the page</p>
  <p>If anyone can at least guide me to a resource that deals with this I'll be thankful.</p>
  <p>App.js</p>
  <pre><code>    import { useState, useEffect } from 'react';
      import './App.css';
      
      import io from &quot;socket.io-client&quot;;
      
      const URL = &quot;localhost:8080&quot;;
      const socket = io(URL, { autoConnect: false });
      
      function App() {
        const [username, setUsername] = useState('');
        const [message, setMessage] = useState('');
        const [users, setUsers] = useState([]);
        const [selectedUser, setSelectedUser] = useState({});
      
        useEffect(() =&gt; {
          socket.on(&quot;users&quot;, (userList) =&gt; {
            userList.forEach((user) =&gt; {
              user.self = (user.userID === socket.id);
              initReactiveProperties(user);
            });
            // put the current user first, and then sort by username
            let temp = (userList.sort((a, b) =&gt; {
              if (a.self) return -1;
              if (b.self) return 1;
              if (a.username &lt; b.username) return -1;
              return a.username &gt; b.username ? 1 : 0;
            }));
            setUsers(temp)
          });
        
          socket.on(&quot;user connected&quot;, (user) =&gt; {
            initReactiveProperties(user);
            setUsers([...users, user]);
            console.log(users)
          });
      
          socket.on(&quot;private message&quot;, ({ message, from }) =&gt; {
            console.log(message, from);
            for (let i = 0; i &lt; users.length; i++) {
              const user = users[i];
              if (user.userID === from) {
                user.messages.push({
                  message,
                  fromSelf: false,
                });
                if (user !== selectedUser) {
                  user.hasNewMessages = true;
                  console.log(&quot;You have one new message&quot;)
                }
                break;
              }
              setUsers(users);
              setSelectedUser(selectedUser);
            }
          });  
        })
      
        const sendMessage = (e) =&gt; {
          e.preventDefault();
          console.log(selectedUser)
          if(selectedUser) {
            socket.emit(&quot;private message&quot;, {
              message,
              to: selectedUser.userID,
            });
            selectedUser.messages.push({
              message,
              fromSelf: true,
            });
          }
          setMessage('');
        }
      
        const initReactiveProperties = (user) =&gt; {
          user.connected = true;
          user.messages = [];
          user.hasNewMessages = false;
        };
      
        const connect = () =&gt; {
          socket.auth = { username };
          socket.connect();
          console.log(`You logged in as ${socket.auth.username}`)
        }
      
        const privateConnect = () =&gt; {
          setSelectedUser(users[1])
        }
      
        const onMessageChange = (e) =&gt; {
          setMessage(e.target.value)
        }
        
        const onUsernameChange = (e) =&gt; {
          setUsername(e.target.value)
        }
      
        return (
          &lt;div className=&quot;App&quot;&gt;
            &lt;h1&gt;Welcome to Chat App&lt;/h1&gt;
            &lt;form onSubmit={sendMessage}&gt;
              &lt;input type=&quot;text&quot; name=&quot;username&quot; placeholder='Type Username' onChange={onUsernameChange} value={username}&gt;&lt;/input&gt;
              &lt;input type=&quot;button&quot; value=&quot;Login&quot; onClick={connect}/&gt;
              &lt;br /&gt;
              &lt;input type=&quot;button&quot; value=&quot;Connect&quot; onClick={privateConnect}/&gt;
              &lt;br /&gt;
              &lt;input type=&quot;text&quot; name=&quot;message&quot; placeholder='Type Message' onChange={onMessageChange} value={message}&gt;&lt;/input&gt;
              &lt;input type=&quot;submit&quot; value=&quot;Send&quot;/&gt;
            &lt;/form&gt;
            {
              selectedUser.messages ? selectedUser.messages.map((data, index) =&gt; {
                return (&lt;h3 key={index}&gt;{(data.fromSelf ? username : selectedUser.username)+ &quot;: &quot; + data.message}&lt;/h3&gt;)
              }) : null
            }
            &lt;hr /&gt;
            {
              users.map((data, index) =&gt; {
                return (&lt;h3 key={index}&gt;{data.username + &quot;: &quot; + data.userID}&lt;/h3&gt;)
              })
            }
          &lt;/div&gt;
        );
      }
      
      export default App;
  </code></pre>
  <p>Server.js</p>
  <pre><code>const app = require('express')();
  const http = require('http').createServer(app);
  const cors = require('cors')
  
  const PORT = 8080;
  
  const io = require('socket.io')(http, {
      cors: &quot;*&quot;
  });
  
  io.use((socket, next) =&gt; {
      const username = socket.handshake.auth.username;
      if (!username) {
        return next(new Error(&quot;invalid username&quot;));
      }
      socket.username = username;
      next();
  });
  
  io.on('connection', (socket) =&gt; {
      console.log(socket.username + &quot; connected&quot;);
  
      const users = [];
      for (let [id, socket] of io.of(&quot;/&quot;).sockets) {
          users.push({
              userID: id,
              username: socket.username,
          });
      }
      console.log(users)
      socket.emit(&quot;users&quot;, users);
  
      socket.broadcast.emit(&quot;user connected&quot;, {
          userID: socket.id,
          username: socket.username,
      });
  
      socket.on(&quot;private message&quot;, ({ message, to }) =&gt; {
          console.log(message, to)
          socket.to(to).emit(&quot;private message&quot;, {
            message,
            from: socket.id,
          });
        });
  
      socket.on(&quot;disconnect&quot;, () =&gt; {
          console.log(socket.username + &quot; disconnected&quot;)
      })
  })
  
  http.listen(PORT, () =&gt; {
      console.log(`Listening on PORT ${PORT}`);
  })
  </code></pre>
  <p>Edit: on the server-side the message is received/sent only once but I think react is getting that message more than once or something</p>
  <p><a href="https://i.stack.imgur.com/cZugE.png" rel="nofollow noreferrer">User A POV</a>
  <a href="https://i.stack.imgur.com/0yJAV.png" rel="nofollow noreferrer">User B POV</a></p>