socket.on回调触发两次问题求助(socket.io 4.5.1版本)
为什么socket.on回调会触发两次?
核心原因:React StrictMode的重复执行机制
在React开发环境中,StrictMode会重复执行useEffect、useState初始化等钩子,目的是帮你提前检测潜在的bug。你的useEffect虽然设置了空依赖数组,但在StrictMode下会被执行两次,导致socket.on('recv_broadcast')被绑定了两次回调。当服务端推送消息时,两个回调都会触发,所以你会看到两次打印和状态更新。
另外,你的socket实例是在组件外部创建的,会被所有组件复用,但如果组件被多次挂载(比如路由切换后重新渲染),也可能导致重复绑定,但最常见的还是StrictMode的影响。
解决方案:添加清理函数解绑事件
在useEffect中添加返回函数,每次组件卸载(或StrictMode重复执行前)解绑对应的事件回调,确保始终只有一个回调被绑定:
修改客户端的useEffect代码:
import { useEffect, useState } from 'react' import { io } from 'socket.io-client'; const socket = io('ws://localhost:3001'); const Main = () => { const [message, setMessage] = useState<string>(''); const [chat, setChat] = useState<string[]>([]); useEffect(() => { // 把回调抽成单独函数,方便精准解绑 const handleRecvBroadcast = (message) => { console.log(message); setChat(state => [...state, message]); }; socket.on('recv_broadcast', handleRecvBroadcast); // 清理函数:组件卸载/重复执行前解绑事件 return () => { socket.off('recv_broadcast', handleRecvBroadcast); }; }, []); const send = () => { setChat(state => [...state, message]); socket.emit('send_broadcast', message); } // ...其他代码 }
额外检查点
- 确认是否在其他组件(比如父组件、同级组件)中也绑定了
recv_broadcast事件 - 从你的服务端代码看,
socket.broadcast.emit只会给当前客户端之外的其他连接推送消息,服务端逻辑不存在重复发送问题
内容的提问来源于stack exchange,提问作者Naruto Uzumaki
相关产品推荐
相关产品推荐

