title: UseEffect hook with socket.io state is not persistent in socket handlers
body: <p>I have the following react component</p>
  
  <pre><code>function ConferencingRoom() {
      const [participants, setParticipants] = useState({})
      console.log('Participants -&gt; ', participants)
  
      useEffect(() =&gt; {
          // messages handlers
          socket.on('message', message =&gt; {
              console.log('Message received: ' + message.event)
              switch (message.event) {
                  case 'newParticipantArrived':
                      receiveVideo(message.userid, message.username)
                      break
                  case 'existingParticipants':
                      onExistingParticipants(
                          message.userid,
                          message.existingUsers
                      )
                      break
                  case 'receiveVideoAnswer':
                      onReceiveVideoAnswer(message.senderid, message.sdpAnswer)
                      break
                  case 'candidate':
                      addIceCandidate(message.userid, message.candidate)
                      break
                  default:
                      break
              }
          })
          return () =&gt; {}
      }, [participants])
  
      // Socket Connetction handlers functions
  
      const onExistingParticipants = (userid, existingUsers) =&gt; {
          console.log('onExistingParticipants Called!!!!!')
  
          //Add local User
          const user = {
              id: userid,
              username: userName,
              published: true,
              rtcPeer: null
          }
  
          setParticipants(prevParticpants =&gt; ({
              ...prevParticpants,
              [user.id]: user
          }))
  
          existingUsers.forEach(function(element) {
              receiveVideo(element.id, element.name)
          })
      }
  
      const onReceiveVideoAnswer = (senderid, sdpAnswer) =&gt; {
          console.log('participants in Receive answer -&gt; ', participants)
          console.log('***************')
  
          // participants[senderid].rtcPeer.processAnswer(sdpAnswer)
      }
  
      const addIceCandidate = (userid, candidate) =&gt; {
          console.log('participants in Receive canditate -&gt; ', participants)
          console.log('***************')
          // participants[userid].rtcPeer.addIceCandidate(candidate)
      }
  
      const receiveVideo = (userid, username) =&gt; {
          console.log('Received Video Called!!!!')
          //Add remote User
          const user = {
              id: userid,
              username: username,
              published: false,
              rtcPeer: null
          }
  
          setParticipants(prevParticpants =&gt; ({
              ...prevParticpants,
              [user.id]: user
          }))
      }
  
      //Callback for setting rtcPeer after creating it in child component
      const setRtcPeerForUser = (userid, rtcPeer) =&gt; {
          setParticipants(prevParticpants =&gt; ({
              ...prevParticpants,
              [userid]: { ...prevParticpants[userid], rtcPeer: rtcPeer }
          }))
      }
  
      return (
              &lt;div id="meetingRoom"&gt;
                  {Object.values(participants).map(participant =&gt; (
                      &lt;Participant
                          key={participant.id}
                          participant={participant}
                          roomName={roomName}
                          setRtcPeerForUser={setRtcPeerForUser}
                          sendMessage={sendMessage}
                      /&gt;
                  ))}
              &lt;/div&gt;
      )
  }
  </code></pre>
  
  <p>the only state it has is a hashTable of <strong>participants</strong> inside the call using useState hook to define it.</p>
  
  <p>then I'm using useEffect to listen on the socket events for the chat room just 4 events </p>
  
  <p>then After that, I'm defining the 4 callback handlers for those events with respect to there order of execution on the server</p>
  
  <p>and last I have another callback function that gets passed to every child participant in the list so that after the child component creates its rtcPeer object it send it to the parent to set it on the participant object in the participant's hashTable</p>
  
  <p>The flow goes like this participants join the room -> <strong>existingParticipants</strong> event gets called -> local participant gets created and added to the participants hashTable then -> <strong>recieveVideoAnswer</strong> and <strong>candidate</strong> gets emitted by the server multiple time as you can see in the screenshot</p>
  
  <p>the first event the state is empty the subsequent two events its there then it's empty again and this pattern keeps repeating one empty state  then the following two is correct and I have no idea what's going on with the state</p>
  
  <p><a href="https://i.stack.imgur.com/ViI5Q.png" rel="noreferrer"><img src="https://i.stack.imgur.com/ViI5Q.png" alt="enter image description here"></a></p>