You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React 18中Socket.io客户端消息重复接收与useEffect执行两次问题

原因分析

React 18的StrictMode在开发环境中会重复执行组件的挂载逻辑(包括useEffect的回调和清理函数),而你当前的Socket.io事件清理逻辑存在错误:socket.off需要传入与绑定阶段完全相同的回调函数才能移除对应的监听器,但你在清理时定义了一个新的匿名函数,导致旧的监听器根本没被清理。每次组件"挂载"(包括StrictMode的二次执行)都会新增一个监听器,最终导致收到两次消息。

解决方案

有两种可行的修复方式,都能在React 18 StrictMode下正常工作:

方案1:复用回调函数(精准移除)

将监听的回调函数提取为独立变量,确保绑定和移除使用同一个函数:

import React, { useEffect } from "react";

function Chat({ socket, username, room }) {
  // 提取独立的回调函数
  const handleReceiveMessage = (data) => {
    console.log(data);
  };

  useEffect(() => {
    socket.on("receive_message", handleReceiveMessage);
    // 清理时传入同一个函数
    return () => {
      socket.off("receive_message", handleReceiveMessage);
    };
  }, [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;

方案2:移除该事件的所有监听器(简洁高效)

如果该事件下只需要一个监听器,可以直接调用socket.off("receive_message")移除该事件的所有监听器:

import React, { useEffect } from "react";

function Chat({ socket, username, room }) {
  useEffect(() => {
    socket.on("receive_message", (data) => {
      console.log(data);
    });
    return () => {
      // 直接移除receive_message事件的所有监听器
      socket.off("receive_message");
    };
  }, [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;

两种方案都能解决重复监听的问题,方案1适合需要精准管理多个同事件监听器的场景,方案2适合简单场景下的快速修复。


内容的提问来源于stack exchange,提问作者Talha Amjad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 16:40:27