Socket.io 和 React:警告:无法对卸载的组件执行 React 状态更新

时间:2021-05-19 00:51:42

标签: node.js reactjs socket.io

我是 React 的新手,我使用 React、socket.io 和 node 实现了一个聊天应用程序。 当用户与某人聊天时,他会连接到一个套接字。它工作正常,但如果用户离开到另一个页面,并再次重新进入同一个聊天,第二个套接字已连接(坏),并且我收到“无法在未安装的组件上执行 React 状态更新”错误.

如果用户离开页面,我确实实现了让套接字离开房间的代码(在第二个 useEffect 上)。但这似乎不起作用。

提前致谢,

错误: enter image description here

部分 React 前端代码:

  useEffect(() => {
      socket.emit("enter chatroom", { conversationId: props.chatId });
      setChatId(props.chatId);

      getMessagesInConversation(props.chatId, (err: Error, result: any) => {
        if (err) {
          setCerror(err.message);
        } else {
          setMessages(buildMessages(result.messages).reverse());
        }
      });

    socket.on("received", (data: any) => {
      setMessages((messages: any) => {
        console.log("messages");
        console.log(messages);
        return [...messages.slice(-4), ...buildMessages(data.newMsg)];
      });

    });

  }, []);

  useEffect(() => {
    return () => {
      socket.emit("leaveChatroom", {
        conversationId: chatId,
      });
    };
  }, [chatId]);

简化的nodejs代码

  private ioMessage = () => {
    this._io.on("connection", (socket) => {
      console.log("socket io connected");
      const socketUser = socket.request.user;

      socket.on("enter chatroom", (data) => {
        const room_status = Object.keys(socket.rooms).includes(
          data.conversationId
        );
        if (!room_status) { // should only join if socket is not already joined.
          socket.join(data.conversationId);
        }
      });


      socket.on("leaveChatroom", (data) => {
        socket.leave(data.conversationId);
      });


      socket.on("chat message", async (msg) => {
        const database = getDB();
        const newMessage = {
          ...msg,
          createdAt: Date.now(),
        };
        await database.collection("message").insertOne(newMessage);
        const messages = await database
          .collection("message")
          .find({ conversationId: msg.conversationId })
          .toArray();

        this._io.to(msg.conversationId).emit("received", {
          newMsg: [messages[messages.length - 1]],
        });

      });

      socket.on("disconnect", (socket) => {
        delete this._users[socketUser.userId];
        console.log("--- disconnect : ", socketUser);
        console.log("--- active users: ", this._users);
      });
    });
  };

详细的错误日志:

enter image description here

0 个答案:

没有答案