React+PeerJS视频聊天应用单次连接触发两次日志问题求助
问题原因与解决方案
核心原因
你遇到的问题大概率是React开发环境的Strict Mode导致的。在React 18的Strict Mode下,开发环境会自动执行两次组件的初始化逻辑(包括useEffect),这就导致你在useEffect里绑定的peer.on('connection')事件被注册了两次。所以每次有新连接进来时,两个回调都会触发,自然就打印了两次日志。
你把Peer实例放在组件外部虽然避免了重复创建实例,但事件监听还是在useEffect里被重复绑定了,所以问题依旧。
解决方案
1. 给useEffect添加清理函数,移除事件监听
修改useEffect,在组件卸载时移除之前绑定的回调,避免重复注册:
useEffect(()=>{ if(!peer) console.log(`No peer detected`); console.log('peer exist: ', peer.id); // 单独定义回调函数,方便后续移除 const handleConnection = (conn)=>{ console.log(`got a connection`); } peer.on('connection', handleConnection); // 清理函数:移除事件监听 return () => { peer.off('connection', handleConnection); } },[])
2. 把事件监听移到组件外部(只绑定一次)
既然Peer实例是全局的,直接在实例创建后绑定事件,不用放到组件的useEffect里,这样只会绑定一次:
const randomPeerId = uuidv4(); const peer = new Peer(randomPeerId); // 直接在这里绑定事件,仅执行一次 peer.on('connection',(conn)=>{ console.log(`got a connection`); }) export function VideoCall() { // ... 组件内部逻辑保持不变 }
3. 临时关闭Strict Mode(仅调试用)
如果只是想快速验证问题,可以在index.tsx里去掉<StrictMode>标签,但不推荐长期这么做——Strict Mode能帮你提前发现很多潜在的组件问题。
额外验证方法
你可以在connection回调里打印conn对象,看看两次触发的连接是否是同一个实例,这样能进一步确认是重复绑定还是PeerJS内部逻辑导致的重复触发。
内容的提问来源于stack exchange,提问作者Shanthan Reddy
相关产品推荐
相关产品推荐

