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

React连接Socket服务器触发两次连接的原因排查

React开发环境下Socket两次连接的原因及解决办法

这是React开发环境专属的问题,根源是React 18的StrictMode机制,和生产环境无关,也不是常规生命周期逻辑导致的。

问题原因

React 18在开发模式的StrictMode中,会重复执行useEffect(挂载阶段执行两次),目的是帮你提前发现组件的潜在问题(比如未清理的副作用)。你的useEffect是空依赖数组,每次执行都会创建一个新的Socket实例并连接服务器,所以服务器会收到两次连接请求。

解决办法

1. 临时调试方案(快速验证)

直接移除项目入口文件(通常是index.js)中的<StrictMode>标签,开发环境下useEffect就只会执行一次,服务器只会收到一个连接。

2. 标准解决方案(推荐)

在useEffect中添加清理函数,确保组件卸载时断开Socket连接。即使StrictMode重复执行,第一次创建的Socket会被清理掉,最终只保留一个有效连接:

const [socket, setSocket] = useState(null)
const [isConnected, setIsConnected] = useState(false)
const [isCreated, setIsCreated] = useState(false)
const [user, setUser] = useState({})

useEffect(() => {
  const socketInstance = openSocket('http://localhost:3030')
  setSocket(socketInstance)

  socketInstance.on('connect', () => {
    setIsConnected(true)
  })
  socketInstance.on('disconnect', () => {
    setIsConnected(false)
  })
  socketInstance.on('userCreated', (payload) => {
    setIsCreated(true)
    setUser(payload)
  })

  // 清理函数:组件卸载/useEffect重新执行时断开连接
  return () => {
    socketInstance.disconnect()
  }
}, [])

const handlerConection = () => {
  if(isConnected) {
    socket.disconnect()
  } else {
    socket.connect()
  }
}

生产环境说明

生产环境下StrictMode不会生效,useEffect只会执行一次,所以上线后不会出现两次连接的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 14:39:54