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
相关产品推荐
相关产品推荐

