[英]Socket.io-client on recieving event running useEffect two times
我正在尝试构建一个聊天应用程序,
问题是每当我向 socket.io 发送一条消息时,我都会收到两次相同的消息。 我两次收到相同的消息 console.log。
现在这是我的 Server.js(使用 express 和 Socket.io)
const express = require("express");
const app = express();
const http = require("http");
const cors = require("cors");
const { Server } = require("socket.io");
app.use(cors());
const server = http.createServer(app);
const io = new Server(server, {
cors: {
origin: "http://localhost:3000",
methods: ["GET", "POST"],
},
});
io.on("connection", (socket) => {
console.log(`User Connected: ${socket.id}`);
socket.on("join_room", (data) => {
socket.join(data);
console.log(`User with ID: ${socket.id} joined room: ${data}`);
});
socket.on("send_message", (data) => {
socket.to(data.room).emit("receive_message", data);
});
socket.on("disconnect", () => {
console.log("User Disconnected", socket.id);
});
});
server.listen(3001, () => {
console.log("SERVER RUNNING");
});
这是我客户的 chat.js 我要发送的道具
const socket = io.connect("http://localhost:3001");
下面是组件
在这个聊天组件中。
import React, { useEffect, useState } from "react";
function Chat({ socket, username, room }) {
useEffect(() => {
socket.on("receive_message", (data) => {
console.log(data);
});
return () => {
socket.off("receive_message", (data) =>
console.log(`receive_message off ${data}`)
);
};
}, [socket]);
return (
<>
<input
type="text"
placeholder="John..."
onChange={(event) => {
console.log(event.target.value);
}}
onKeyPress={(event) => {
if (event.key === "Enter") {
socket.emit("send_message", {
room: room,
author: username,
message: event.target.value,
});
}
}}
/>
</>
);
}
export default Chat;
打开第二个选项卡后,我看到两个 console.logs 弹出相同的消息。 谁能告诉我我在这里做错了什么或在这里遗漏了什么?
我尝试从 index.js 中删除 React.StrictMode,它解决了问题,但我不想删除它。 此外,在将我的反应版本从 18 转移到 17 之后,它也解决了这个问题,我如何在 18 中解决这个问题。我还想在同一个 chat.js 组件中解决这个问题。 任何帮助,将不胜感激。
谢谢。
问题在这里:
useEffect(() => {
socket.on("receive_message", (data) => {
console.log(data);
});
return () => {
socket.off("receive_message", (data) =>
console.log(`receive_message off ${data}`)
);
};
}, [socket]);
您正在正确地尝试在返回时删除一个侦听器,但问题是您正在删除错误的侦听器——您必须传递与要删除的完全相同的 function(因为您可以在一个事件上有两个侦听器)。 这意味着当第二次渲染发生在安全模式下时,您有两个侦听器添加到该事件。
尝试这个:
useEffect(() => {
const receiveMessage = (data) => {
console.log(data)
}
socket.on("receive_message", receiveMessage);
return () => {
socket.off("receive_message", receiveMessage);
};
}, [socket]);
这将确保删除正确的 function。 如果这有效,请务必标记我的答案!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.