[英]Array.push pushes the content multiple times
useEffect(() => {
socket.on("private message", ({ content, from }) => {
console.log(content, from, "content & form");
for (let i = 0; i < usersList.length; i++) {
var user = usersList[i];
if (user.userID === from) {
console.log("user from");
user.messages.push({
content,
fromSelf: false,
});
if (user !== selectedUser) {
console.log("user to");
user.hasNewMessages = true;
}
break;
}
}
});
}, [usersList, selectedUser]);
I am using socket to make private chat, but the thing is that user.messages.push, pushes the content multiple times because it is inside the for loop, here usersList is a list of all connected users, so if 3 users are connected, it will loop 3 times and then the messages will be pushed 3 times, How do I fix this so that it only pushes one time and not with relative to the number of users connected?我正在使用套接字进行私人聊天,但问题是 user.messages.push 多次推送内容,因为它在 for 循环内,这里 usersList 是所有连接用户的列表,所以如果连接了 3 个用户,它将循环 3 次,然后消息将被推送 3 次,我该如何解决这个问题,以便它只推送一次而不是相对于连接的用户数量?
selectedUser is the user that the loggedIn user wishes to initiate a conversation with selectedUser 是已登录用户希望与其发起对话的用户
NOTE : I need a solution except for maintaining a state and then changing it with first iteration and conditionally running the logic, Pls tell me other that this.注意:我需要一个解决方案,除了维护一个 state 然后通过第一次迭代更改它并有条件地运行逻辑,请告诉我其他的。
You are attaching new listeners each time the useEffect
hook runs after usersList
or selectedUser
update.每次在usersList
或selectedUser
更新后运行useEffect
挂钩时,您都会附加新的侦听器。 Each time the effect callback runs a new listener is added, and each one runs the same "private message" event callback.每次效果回调运行时都会添加一个新的侦听器,并且每个侦听器都会运行相同的“私人消息”事件回调。 This is where the message content duplication is occurring.这是发生消息内容重复的地方。
I suspect you want only one listener.我怀疑你只想要一个听众。 Use an empty dependency array so the effect runs only once on component mount.使用一个空的依赖数组,这样效果只会在组件挂载时运行一次。
const messageHandler = ({ content, from }) => {
console.log(content, from, "content & form");
for (let i = 0; i < usersList.length; i++) {
var user = usersList[i];
if (user.userID === from) {
console.log("user from");
user.messages.push({
content,
fromSelf: false,
});
if (user !== selectedUser) {
console.log("user to");
user.hasNewMessages = true;
}
break;
}
}
}
useEffect(() => {
socket.on("private message", messageHandler);
}, []);
You may see some lint warning about unspecified dependency on messageHandler
, if necessary you can disable the linter for this as follows:您可能会看到一些关于对messageHandler
的未指定依赖的 lint 警告,如有必要,您可以为此禁用 linter,如下所示:
useEffect(() => {
socket.on("private message", messageHandler);
// Run effect only on component mount
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
I think you need to keep the user.userID in your client and remove the for loop in the socket.on "private message" Event.我认为您需要将 user.userID 保留在客户端中,并删除 socket.on “私人消息”事件中的 for 循环。
Something like this:像这样的东西:
// Global (Example values)
const currentUser = 1;
const usersList = [2, 3, 4, 5];
useEffect(() => {
socket.on("private message", ({ content, from }) => {
console.log(content, from, "content & form");
if (currentUser === from) { // The currentUser send a message to another user
console.log("user from");
user.hasNewMessages = true;
} else if (user !== from) { // The currentUser receive a message from another user
console.log("user to");
user.messages.push({
content,
fromSelf: false,
});
}
});
}, [usersList, currentUser]);
This is what needed to be doing:这是需要做的:
if (shipments.length > 0) {
shipments.map((item, key: number) => {
if (item.lookup_scan === newobj.lookup_scan) {
shipments[key] = newobj;
}
});
shipments.push(newobj);
} else {
shipments.push(newobj);
}
This is what I was doing:这就是我正在做的事情:
if (shipments.length > 0) {
shipments.map((item, key: number) => {
if (item.lookup_scan === newobj.lookup_scan) {
shipments[key] = newobj;
} else {
shipments.push(newobj);
}
});
} else {
shipments.push(newobj);
}
const messageHandler = ({ content, from }: any) => {
console.log(content, from, "content & form");
var user;
for (let i = 0; i < usersList.length; i++) {
user = usersList[i];
}
if (user && user.userID === from) {
console.log("user from");
user.messages.push({
content,
fromSelf: false,
});
if (user !== selectedUser) {
console.log("user to");
user.hasNewMessages = true;
}
}
};
useEffect(() => {
socket.on("private message", messageHandler);
}, [usersList]);
This solved the bug, I had to move the Array.push out of the for loop.这解决了这个错误,我不得不将 Array.push 移出 for 循环。
Thanks everyone.感谢大家。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.