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?
Screenshot of the error after the first version of the below answer:
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]);