繁体   English   中英

Socket.io-client 收到运行 useEffect 两次的事件

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM