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

React useEffect中Socket.io事件触发两次,清理订阅仍无效

React Strict Mode下Socket.io事件触发两次的解决方案

问题原因

React Strict Mode在开发环境中会刻意重复执行组件的挂载/卸载流程(即两次调用useEffect,中间执行一次清理函数),目的是检测未正确清理的副作用。你遇到的事件触发两次,大概率是因为:

  • 你在组件内部创建Socket.io实例,Strict Mode导致组件两次挂载时生成了两个独立的socket连接,每个连接都绑定了事件监听,服务器发消息时两个连接都会收到通知,触发两次回调。
  • 即使使用全局socket实例,若socket.off未正确移除回调(不过你的代码中每次useEffect的回调是独立的,第一次清理时用的是绑定的同一个回调,这种情况概率较低)。

解决方案

1. 使用全局单例Socket实例(推荐)

将Socket.io实例抽离到单独模块中,确保整个应用只有一个连接:

// socket.js
import { io } from 'socket.io-client';

// 替换为你的服务器地址
export const socket = io('http://your-server-domain');

在组件中导入这个单例并使用:

import { socket } from './socket';
import { useEffect } from 'react';

function ChatComponent() {
  useEffect(() => {
    const handleNewMessage = (data) => {
      console.log("new chat received");
      // 处理消息逻辑
    };
    socket.on("new-chat-message", handleNewMessage);
    
    // 清理函数:移除当前回调
    return () => {
      socket.off("new-chat-message", handleNewMessage);
    };
  }, []);

  return <div>聊天组件</div>;
}

这种方式下,Strict Mode的两次挂载只会绑定/解绑同一个socket实例的回调,最终只会保留一个有效监听,不会出现两次触发。

2. 用useRef确保Socket实例仅创建一次

如果必须在组件内部创建Socket实例,使用useRef保存实例,避免重复创建:

import { io } from 'socket.io-client';
import { useEffect, useRef } from 'react';

function ChatComponent() {
  const socketRef = useRef(null);

  useEffect(() => {
    // 仅在第一次挂载时创建socket实例
    if (!socketRef.current) {
      socketRef.current = io('http://your-server-domain');
    }
    const socket = socketRef.current;

    const handleNewMessage = (data) => {
      console.log("new chat received");
      // 处理消息逻辑
    };
    socket.on("new-chat-message", handleNewMessage);
    
    return () => {
      socket.off("new-chat-message", handleNewMessage);
    };
  }, []);

  return <div>聊天组件</div>;
}

3. 临时禁用Strict Mode(仅调试用)

如果只是想快速验证问题,可以移除App.tsx中的<React.StrictMode>标签,但不推荐长期使用——Strict Mode能帮你提前发现很多潜在的副作用问题,对生产环境代码质量有帮助。

额外说明

Strict Mode的重复执行仅发生在开发环境,生产环境下不会出现该行为。但开发环境的问题建议优先通过前两种方案解决,避免隐藏其他潜在bug。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 01:15:29