Socket connection does not disconnect at useEffect cleanup function

52 Views Asked by At

I have this code :

useEffect(() => {
    const init = async () => {
      try {
        socketRef.current = await initSocket();

        socketRef.current.on("connect_error", (err) => handleErrors(err));
        socketRef.current.on("connect_failed", (err) => handleErrors(err));

        function handleErrors(e) {
          console.log("socket error", e);
          toast.error("Socket connection failed, try again later.");
          navigate("/dashboard");
        }
        function DisconnectRoom({ socketId, username }) {
          toast.info(`${username} left the room`);
          setClients((prev) => {
            return prev.filter((client) => client.socketId !== socketId);
          });
        }
        function JoinedRoom({ clients, userName, socketId }) {
          if (username !== userName) {
            toast.success(`${userName} joined the room!`);
            socketRef.current.emit(Actions.SYNC_CODE, {
              roomId,
              code: codeRef.current,
              socketId,
              name: "all",
            });
          }
          setClients(clients);
        }
        socketRef.current.emit(Actions.JOIN, {
          roomId,
          username,
        });

        socketRef.current.on(Actions.JOINED, JoinedRoom);

        socketRef.current.on(Actions.DISCONNECTED, DisconnectRoom);
      } catch (e) {
        console.log(e);
      }
    };
    init();

    return () => {
      socketRef.current.disconnect();
      socketRef.current.off(Actions.DISCONNECTED);
      socketRef.current.off(Actions.JOINED);
    };
  }, []);

The problem is when the cleanup function executes it gives an error that socketRef.current is null. I have already tried to put a condition -

if(socketRef.current) {
    socketRef.current.disconnect();
    socketRef.current.off(Actions.DISCONNECTED);
    socketRef.current.off(Actions.JOINED);
}

But now it connects a client two times probably because in strictmode react call a function 2 times. Could anyone please help me to fix this

I tried to connect one client to socket but as mentioned above if I check socketRef.current then it connects a client two times and if I don't the it gives error that socketRef.current is null.

1

There are 1 best solutions below

3
Egge On

Is it a requirement to use a ref for the socket connection? Why don’t you use a variable inside the useEffects scope to keep track of your socket instance?

Pseudo-code:


let socket;
socket = createConnection();
return () => {
  if (socket) {
    socket.disconnect();
  }
}