React组件卸载后订阅没清理,内存泄漏怎么解决?
我在用React做聊天功能,组件里用了WebSocket监听消息。每次切换页面再回来,发现消息会重复收到好几遍,怀疑是之前订阅没清理掉。
我试过在useEffect里return一个清理函数,但好像没生效。比如这样:
useEffect(() => {
const ws = new WebSocket('ws://example.com');
ws.onmessage = (e) => setMessage(e.data);
return () => ws.close();
}, []);
但内存快照里还是能看到旧的监听器残留,是不是哪里写错了?该怎么正确清理订阅?
这样改一下:
还有个常见坑:如果用了React 18的严格模式,开发环境会先挂载→清理→再挂载一次。你这个代码在第二次挂载时又会新建连接,如果第一次的ws还没彻底关掉,就会出现多个连接同时存在的情况。
可以加个状态防止重复创建:
另外提醒一下,setMessage在组件卸载后调用会出warning,虽然不直接导致内存泄漏,但最好也保护一下:
这样内存快照里应该就干净了。