组件卸载后如何关闭WebSocket连接?
解决组件卸载时关闭WebSocket连接的问题
你的代码目前存在几个关键问题,导致无法在组件卸载时正常关闭WebSocket连接:
- 没有保存创建的WebSocket实例,卸载时找不到需要关闭的连接对象
timeout未通过useRef存储,存在内存泄漏风险mountedCount的逻辑冗余,直接用useRef管理socket实例更合理
修改后的代码如下:
import { useEffect, useRef } from 'react'; // ... 其他必要导入 const YourComponent = () => { const socketRef = useRef(null); const timeoutRef = useRef(null); useEffect(() => { const connectWebSocket = () => { const socketURL = 'socket url here'; const socket = new WebSocket(socketURL); socket.onopen = () => { console.log('socket open'); }; socket.onclose = (closeEvent) => { if (closeEvent.wasClean) return; // 重连前清除已有超时任务 if (timeoutRef.current) clearTimeout(timeoutRef.current); timeoutRef.current = setTimeout(() => { connectWebSocket(); }, envVariables.webSocketReconnectionTimeout); }; socket.onerror = () => { console.log('error here'); }; socket.onmessage = (messageEvent) => { console.log('got the message'); }; socketRef.current = socket; }; connectWebSocket(); // 组件卸载时执行清理 return () => { // 清除重连超时任务 if (timeoutRef.current) clearTimeout(timeoutRef.current); // 关闭WebSocket连接 if (socketRef.current) { // 传入正常关闭状态码,避免触发重连逻辑 socketRef.current.close(1000, 'Component unmounted'); socketRef.current = null; } }; }, [dispatch, userData.userInformation, wss.connectionStatus]); // ... 组件其他业务逻辑 };
关键修改说明:
- 用
socketRef存储WebSocket实例,确保在清理函数中能访问到当前连接 - 用
timeoutRef管理重连超时ID,避免内存泄漏,同时在重连前清除旧的超时任务 - 移除
mountedCount,利用useEffect的依赖数组控制连接创建时机,不会重复生成实例 - 关闭连接时传入状态码
1000(正常关闭),让onclose中的wasClean为true,跳过不必要的重连
内容的提问来源于stack exchange,提问作者ar j
相关产品推荐
相关产品推荐

