title: React state being set back to initial [] when socket.on() is triggered inside useEffect()
body: <p>I am a noob with React functional components and this is my first try with socket-io.</p>
  <p>I have a functional component which is an inbox that renders up to ten &quot;alert&quot; rows per page from an <code>InboxList</code> array. I am using socket-io so that multiple clients can see in real-time whenever a specific row is clicked (the row turns grey).</p>
  <p>The problem is that <em>most</em> times the client (observing the row change, not clicking) will have their inbox empty (0 alerts in InboxList) once an alert is clicked.</p>
  <p>After some debugging, I found that as soon as the socket.on('alertClicked') is triggered, my inboxList state is empty (instead of having the same 10 alerts I am expecting).</p>
  <p>This will cause my <code>inboxListCopy</code> inside <code>greyOutAlert()</code> to of course be empty.</p>
  <p>If anyone has suggestions that would be greatly appreciated.</p>
  <p>Functional component code for context:</p>
  <pre><code>import React, { useState, useContext, useEffect } from 'react';
  import io from 'socket.io-client';
  import Axios from 'axios';
  import Table from 'react-bootstrap/Table';
  import Pagination from 'react-responsive-pagination';
  import { useHistory } from 'react-router-dom';
  import '../../App.css';
  
  let socket;
  
  export default function Inbox() {
  
      const [token, setToken] = useState(() =&gt; {
          return localStorage.getItem('auth-token');
      });
      const [currentPage, setCurrentPage] = useState(() =&gt; {
          return 1;
      });
      const [alertCount, setAlertCount] = useState(() =&gt; {
          return 5;
      });
      const [inboxList, setInboxList] = useState(() =&gt; {
          return [];
      });
  
      const history = useHistory();
  
      useEffect(() =&gt; {
          const connectionOptions = {
              &quot;force new connection&quot; : true,
              &quot;reconnectionAttempts&quot;: &quot;Infinity&quot;, 
              &quot;timeout&quot; : 10000,                  
              &quot;transports&quot; : [&quot;websocket&quot;] 
          }
  
          socket = io('http://localhost:5000', connectionOptions);
          
          return () =&gt; {
              socket.emit('disconnected');
              socket.off();
          }
      }, []);
  
      useEffect(()=&gt;{
          fetchAlertCount();
       },[])
  
      useEffect(()=&gt;{
          socket.on('alertClicked', (alertId) =&gt; {
              greyOutAlert(alertId);
            });
       },[])
  
      const greyOutAlert = (alertId) =&gt; {
          let inboxListCopy = [...inboxList];
          for (let i = 0; i &lt; inboxListCopy.length; i++) {
              if (inboxListCopy[i]._id === alertId) {
                  inboxListCopy[i].hasBeenReviewed = true;
                  break;
              }
          }
          setInboxList(inboxListCopy);
      };
  
      useEffect(() =&gt; {
          fetchAlerts();
      },[currentPage]);
  
      const fetchAlertCount = async () =&gt; {
          const config = {
              headers: {
                  'x-auth-token': token,
              }
          };
          const alertCountResponse = await Axios.get('http://localhost:5000/alertinbox/totalAlerts', config);
          setAlertCount(alertCountResponse.data.count);
      };
  
      const fetchAlerts = async () =&gt; {
          const config = {
              headers: {
                  'x-auth-token': token,
                  'page': currentPage
              }
          };
          const alertsResponse = await Axios.get('http://localhost:5000/alertinbox/', config);
          setInboxList(alertsResponse.data.alerts);
      };
  
      const handleClick = (alertId, messageType) =&gt; {
  
          socket.emit('clientClickedAlert', {alertId});
  
          switch (messageType) {
              case '2+ Minutes':
                  history.push(`/2plusminutes/${alertId}`, {alertId});
                  break;
              case 'SOS':
                  history.push(`/sos/${alertId}`, {alertId});
                  break;
              case 'Low Battery':
                  history.push(`/lowbattery/${alertId}`, {alertId});
                  break;
          };
      };
  
      return (
          &lt;React.Fragment&gt;
              &lt;div id='inbox'&gt;
                  &lt;Table&gt;
                      &lt;thead&gt;
                          &lt;tr&gt;
                              &lt;th&gt;Alert Type&lt;/th&gt;
                              &lt;th&gt;Customer Name&lt;/th&gt;
                              &lt;th&gt;Timestamp&lt;/th&gt;
                              &lt;th&gt;Vehicle&lt;/th&gt;
                          &lt;/tr&gt;
                      &lt;/thead&gt;
                      &lt;tbody&gt;
                          {inboxList.map(function(alert, index){
                              return(
                                  &lt;tr key={index} onClick={() =&gt; handleClick(alert._id, alert.messageType)} className={alert.hasBeenReviewed ? 'darken' : 'lighten'}&gt;
                                      &lt;td&gt;{alert.messageType}&lt;/td&gt;
                                      &lt;td&gt;{alert.ownerName}&lt;/td&gt;
                                      &lt;td&gt;{alert.createdAt}&lt;/td&gt;
                                      &lt;td&gt;{alert.vehicle.year + ' ' + alert.vehicle.make + ' ' + alert.vehicle.model}&lt;/td&gt;
                                  &lt;/tr&gt;
                              )
                          })}
                      &lt;/tbody&gt;
                  &lt;/Table&gt;
              &lt;/div&gt;
              &lt;Pagination
                  current={currentPage}
                  total={Math.ceil(alertCount/10)}
                  onPageChange={setCurrentPage}
                  maxWidth={100}
              /&gt;
          &lt;/React.Fragment&gt;
      )
  }
  </code></pre>