React.js中点击事件触发WebSocket.send()未执行问题排查求助
React WebSocket send方法执行无效果解决方案
你代码中console.log("Sending message")能正常打印,说明ws.send()代码已经被调用,观测到的"未执行"实际是消息没有成功发送到服务端,可按以下方案排查:
- WebSocket实例重复创建(最常见原因)
原因:如果直接在React组件顶层初始化WebSocket实例,组件每次重渲染都会创建新的连接,旧连接被自动关闭,你调用send方法的可能是已经失效的旧实例,即使代码执行也不会传输到服务端,React严格模式下开发环境会触发两次组件挂载,会放大这个问题。
解决方案:用useRef存储实例,配合useEffect仅在组件挂载时初始化一次,卸载时主动关闭连接,参考代码:import { useRef, useEffect, useState } from 'react'; const NotificationComponent = () => { const wsRef = useRef(null); const [message, setMessage] = useState(''); useEffect(() => { // 仅初始化一次WebSocket实例 wsRef.current = new WebSocket("ws://192.168.18.112:8000/ws/notification/"); wsRef.current.onopen = (e) => { console.log("connect"); }; // 新增错误监听排查连接问题 wsRef.current.onerror = (err) => { console.error("WebSocket连接异常:", err); }; // 新增关闭监听排查连接断开问题 wsRef.current.onclose = (e) => { console.log("WebSocket连接断开:", e.code, e.reason); }; // 组件卸载时关闭连接避免内存泄漏 return () => { if (wsRef.current?.readyState === WebSocket.OPEN) { wsRef.current.close(); } }; }, []); // 空依赖数组保证仅执行一次 const sendNotification = (e) => { console.log("click"); const ws = wsRef.current; if (!ws) return; if (ws.readyState === WebSocket.OPEN && message !== "") { // 修正传参:发送业务变量而非固定字符串 ws.send(message); console.log("Sending message"); } else if (ws.readyState === WebSocket.CONNECTING) { // 避免重复绑定open事件,执行后移除监听 const sendOnce = () => { if (message !== "") { ws.send(message); console.log("连接建立后发送消息"); } ws.removeEventListener("open", sendOnce); }; ws.addEventListener("open", sendOnce); console.log("Connecting state,消息将在连接建立后发送"); } else { console.log("连接已关闭或异常,无法发送消息"); } }; // 其余组件逻辑... } - send方法传参错误
原因:你原有代码中ws.send("message")发送的是固定字符串"message",而非逻辑中判断的非空业务变量message,如果后端按照约定字段接收,会误以为没有收到消息。
解决方案:修改为ws.send(message)发送实际业务数据。 - 缺少异常监听无法定位问题
原因:原有代码没有监听error和close事件,无法判断是否是跨域、后端服务异常、路径错误等问题导致的消息发送失败,即使send代码执行,也可能因为连接失效无法传输。
解决方案:参考上面的代码新增异常监听,打印日志即可快速定位连接层问题。
内容的提问来源于stack exchange,提问作者hania
相关产品推荐
相关产品推荐

