WebSocket报错:Cannot set properties of null (setting 'onmessage') 求助
问题分析与修复方案
错误根源
你在response()方法的第一行就执行了this.socketRef = null,直接将WebSocket实例置空,后续尝试给null设置onmessage属性,必然触发Cannot set properties of null错误。
1. 修复WebSocketService的response方法
移除错误的null赋值,同时完善连接状态校验与Promise的异常处理:
class WebSocketService { ... constructor() { this.socketRef = null; } // 新增连接初始化方法(确保先建立连接再监听消息) connect(wsUrl) { this.socketRef = new WebSocket(wsUrl); return new Promise((resolve, reject) => { this.socketRef.onopen = () => resolve("连接成功"); this.socketRef.onerror = (err) => reject(err); }); } ... response() { // 移除 this.socketRef = null; 这行错误代码 return new Promise((resolve, reject) => { // 先校验WebSocket是否处于可用状态 if (!this.socketRef || this.socketRef.readyState !== WebSocket.OPEN) { reject(new Error("WebSocket未连接或已关闭")); return; } this.socketRef.onmessage = e => { try { const response = JSON.parse(e.data); console.log(`!!!! response: ${JSON.stringify(response)} !!!`); resolve(response); } catch (parseErr) { reject(new Error(`解析消息失败:${parseErr}`)); } }; // 监听错误与关闭事件,避免Promise一直处于pending状态 this.socketRef.onerror = (err) => reject(err); this.socketRef.onclose = () => reject(new Error("WebSocket连接已关闭")); }); } }
2. 修正useEffect的调用逻辑
确保先建立WebSocket连接,再调用监听方法,同时处理组件卸载时的清理:
useEffect(() => { let isComponentMounted = true; // 先建立连接,再监听服务器消息 WebSocketInstance.connect("你的WebSocket服务地址") .then(() => WebSocketInstance.response()) .then((res) => { if (!isComponentMounted) return; // 注意:res已经是JSON解析后的对象,无需再次解析res.text received.current = res?.data || ""; }) .catch((err) => { console.error("WebSocket处理异常:", err); }); // 组件卸载时清理WebSocket连接 return () => { isComponentMounted = false; if (WebSocketInstance.socketRef) { WebSocketInstance.socketRef.close(); WebSocketInstance.socketRef = null; } }; }, []); // 空依赖确保只在组件挂载时执行一次
3. 额外注意事项
- 驱动端的代码发送逻辑,必须在WebSocket连接成功后再触发,避免发送失败。
- 如果需要持续监听服务器消息(而非仅接收一次),建议不要用Promise包裹
onmessage,而是直接在connect方法中注册持久化的消息回调,或者提供专门的订阅方法管理监听函数。
内容的提问来源于stack exchange,提问作者Emm
相关产品推荐
相关产品推荐

