为什么 React Component 在从 socket.io 获取事件时会渲染很多次?
Why React Component render many time when get event from socket.io?
我正在为我的项目社交网络网站使用 socket.io,当用户连接时我加入,但是当我通过群聊从 socket.io 收到消息时,我的组件多次呈现消息。示例:我的群组有 4 个人,我向群组发送消息,然后一个用户收到消息 3 次,我尝试了很多次但没有成功,这是我的代码:
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('');
};
我在后端的代码:
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 image
任何人都可以帮助我。谢谢!!!
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 });
});
});
将此更改为
socket.on("newMessage", ({ message, conversation }) => {
socket.in(conversation._id).emit("getMessage", { message, conversation });
}
});
您发送消息 conversation.members.length 次,只需发送一次。
我正在为我的项目社交网络网站使用 socket.io,当用户连接时我加入,但是当我通过群聊从 socket.io 收到消息时,我的组件多次呈现消息。示例:我的群组有 4 个人,我向群组发送消息,然后一个用户收到消息 3 次,我尝试了很多次但没有成功,这是我的代码: 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('');
};
我在后端的代码:
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 image 任何人都可以帮助我。谢谢!!!
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 });
});
});
将此更改为
socket.on("newMessage", ({ message, conversation }) => {
socket.in(conversation._id).emit("getMessage", { message, conversation });
}
});
您发送消息 conversation.members.length 次,只需发送一次。