Search code examples
javascriptreactjssocketssocket.ioreal-time

How to hold the socket instance on page refresh?


on my root component I am setting up the the socket like this,

const [socket, setSocket] = useState(null);
const setupSocket = () => {
    const token = localStorage.getItem('CC_Token');
    if (token && token.length > 0 && !socket) {
      const newSocket = io('http://localhost:8000', {
        query: {
          token: localStorage.getItem('CC_Token'),
        },
      });

      newSocket.on('disconnect', () => {
        setSocket(null);
        setTimeout(setupSocket, 3000);
        makeToast('error', 'Socket disconnected!');
      });

      newSocket.on('connect', () => {
        makeToast('success', 'Socket Connected');
      });

      setSocket(newSocket);
    }
  };

  useEffect(() => {
    setupSocket();
  }, []);

and using react-router I am passing the socket instance as a prop.

<Route
  exact
  path="/chatroom/:id"
  render={() => <ChatroomPage socket={socket} />}
/>;

it works fine until, I refresh the page. when I refresh the page socket gets back to its initial state (null) so that, I can not send any message.

This snippet is from CharoomPage component.

  React.useEffect(() => {
    if (socket) {
      socket.emit("joinRoom", {
        chatroomId,
      });
    }

    return () => {
      //Component Unmount
      if (socket) {
        socket.emit("leaveRoom", {
          chatroomId,
        });
      }
    };
    //eslint-disable-next-line
  }, []);

On page refresh socket is null, so It can not emit the joinRoom event.

How can I implement this so that on page refresh I emit the joinRoom event?


Solution

  • Well if you refresh the page, socket will go back to initial state null and the useEffect should run.

    But your ChatRoomPage useEffect do not take socket into the second arguments.

    Try with

    const ChatRoom = ({socket}) => {
      useEffect(() => {
        if( !socket) return;
    
        socket.emit("joinRoom", {chatroomId});
        return () => {
          if (!socket) return;
          socket.emit("leaveRoom", {chatroomId});
        };
      }, [socket]); //<== here
    };
    

    The strange part of your bug is that it sometime works before refresh.