'Why React Component render many time when get event from socket.io?
I am using socket.io for my project social network web, when user connect I join, but when I get message from socket.io by group chat, My component render message many time. Example: My group has 4 people, I send message to group then one user get message 3 times, I tried many time but not working, Here is my code: socket.ts:
import io from 'socket.io-client';
export const socket = io('http://localhost:8800');
App.ts:
useEffect(() => {
if (user) {
socket.emit('setup', user);
}
}, [user]);
ChatBox.tsx:
useEffect(() => {
socket.emit('join chat', conversationId);
}, [conversationId]);
useEffect(() => {
socket.on('typing', () => setIsTyping(true));
socket.on('stop typing', () => setIsTyping(false));
}, []);
useEffect(() => {
socket.on('getMessage', (data: { message: messageType; conversation: conversationType }) => {
console.log(data);
setMessages((prev) => [data.message, ...prev]);
});
}, []);
useEffect(() => {
const getMessages = async () => {
setIsFetchingMessage(true);
if (conversationId) {
const res = await getMessagesApi(conversationId);
setMessages(res);
}
setIsFetchingMessage(false);
};
getMessages();
}, [conversationId]);
const handleChangeMessageText = (e: React.ChangeEvent<HTMLInputElement>) => {
setMessageContent(e.target.value);
socket.emit('typing', conversationId);
if (typingTimeout.current) {
clearTimeout(typingTimeout.current);
}
typingTimeout.current = setTimeout(() => {
socket?.emit('stop typing', conversationId);
}, 2000);
};
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
if (conversationId) {
const res = await createMessageApi(conversationId, messageContent);
if (res) {
socket.emit('newMessage', { message: res, conversation: currentConversation });
setMessages((prev) => [res, ...prev]);
setConversations((prev) =>
prev.map((c) => (c._id === conversationId ? { ...c, lastMessage: res } : c))
);
}
}
setMessageContent('');
};
My code in backend:
io.on("connection", (socket) => {
socket.on("setup", (userData) => {
console.log("User connect: ", userData._id);
addNewUser(userData, socket.id);
socket.join(userData._id);
socket.emit("onlineUsers", onlineUsers);
});
socket.on("join chat", (room) => {
socket.join(room);
console.log("User joined chat: ", room);
});
socket.on("newMessage", ({ message, conversation }) => {
conversation.members.forEach((member) => {
if (member._id == message.sender._id) return;
const user = getUser(member._id);
socket.in(conversation._id).emit("getMessage", { message, conversation });
});
});
Error: error image Anyone can help me. Thanks!!!
Solution 1:[1]
socket.on("newMessage", ({ message, conversation }) => {
conversation.members.forEach((member) => {
if (member._id == message.sender._id) return;
const user = getUser(member._id);
socket.in(conversation._id).emit("getMessage", { message, conversation });
});
});
Change this to
socket.on("newMessage", ({ message, conversation }) => {
socket.in(conversation._id).emit("getMessage", { message, conversation });
}
});
You are emitting the message conversation.members.length times, you only need to emit it once.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |