Home > Blockchain >  Why Socket.io client in React perform all event two times?
Why Socket.io client in React perform all event two times?

Time:01-17

I am trying to use Socket.io client in a Next.js app. But I am facing one problem; when I perform an event socket runs two times. But I am not finding any solutions. Can anyone help me to debug this problem?

I am using React Context to create a socket provider.

socket.context.tsx-

import { createContext, FC, useContext } from "react";
import { io, Socket } from "socket.io-client";
import { getCookie } from "cookies-next";

const token = getCookie("session")

const socket = io(process.env.NEXT_PUBLIC_WS || "http://localhost:5000", {
    extraHeaders: {
        "authorization": token?.toString() || ""
    }
})

//types
interface SocketContextInterface {
    socket: Socket
}
const SocketContext = createContext<SocketContextInterface>({ socket });

interface Props {
    children: React.ReactNode
}

const SocketProvider: FC<Props> = (props) => {
    return (
        <SocketContext.Provider value={{ socket }}>
            {props.children}
        </SocketContext.Provider>
    );
};

export const useSocket = () => useContext(SocketContext)

export default SocketProvider;

And then, I am using it in one component-

const { socket } = useSocket();

//Performing create message on onSubmit handler
const onSubmit: SubmitHandler<Inputs> = (submitData) => {
    const MessageData = {
        conversation: selected,
        message: {
            text: submitData.message
        }
    }
    socket.emit("createMessage", MessageData);
    reset();
}

//And then I am try to listen event

useEffect(() => {
    socket.on("createMessage", (data: MessageData) => {
        setMessages((prev: MessageData[]) => [...prev, data])
    })
}, [socket])
// But this performs two times

Here socket.on perform two times. How can I solve this problem?

enter image description here

Screenshot of the error after the first version of the below answer:

enter image description here

CodePudding user response:

I think your createMessag listener is being registered two times in memory, either because of a re-render or StrictMode. Add a clean-up, like so:

useEffect(() => {
  const listener = (data: MessageData) => {
    setMessages((prev: MessageData[]) => [...prev, data]);
  };
  socket.on("createMessage", listener);
  return () => {
    socket.off("createMessage", listener);
  };
}, [socket]);
  • Related