From e65a210cb32709cfac02c31d1e95dd8e500d5136 Mon Sep 17 00:00:00 2001 From: Haileyesus Date: Sat, 31 Jan 2026 11:35:43 +0300 Subject: [PATCH] fix: use `useRef` for WebSocketContext The main issue with using states was, previously the websocket never closed properly on unmount, so multiple connections could be opened. This was because the useEffect cleanup function was closing an old websocket (that was initialized to null) instead of the current one. We could have fixed this by adding `ws` to the useEffect dependency array, but this was unnecessary since `ws` doesn't affect rendering so we shouldn't use a state. --- src/contexts/WebSocketContext.jsx | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/contexts/WebSocketContext.jsx b/src/contexts/WebSocketContext.jsx index 14782d3..f6a28dd 100644 --- a/src/contexts/WebSocketContext.jsx +++ b/src/contexts/WebSocketContext.jsx @@ -16,7 +16,7 @@ export const useWebSocket = () => { }; const useWebSocketProviderState = () => { - const [ws, setWs] = useState(null); + const wsRef = useRef(null); const [messages, setMessages] = useState([]); const [isConnected, setIsConnected] = useState(false); const reconnectTimeoutRef = useRef(null); @@ -28,8 +28,8 @@ const useWebSocketProviderState = () => { if (reconnectTimeoutRef.current) { clearTimeout(reconnectTimeoutRef.current); } - if (ws) { - ws.close(); + if (wsRef.current) { + wsRef.current.close(); } }; }, []); // Keep dependency array but add proper cleanup @@ -61,7 +61,7 @@ const useWebSocketProviderState = () => { websocket.onopen = () => { setIsConnected(true); - setWs(websocket); + wsRef.current = websocket; }; websocket.onmessage = (event) => { @@ -75,7 +75,7 @@ const useWebSocketProviderState = () => { websocket.onclose = () => { setIsConnected(false); - setWs(null); + wsRef.current = null; // Attempt to reconnect after 3 seconds reconnectTimeoutRef.current = setTimeout(() => { @@ -93,15 +93,16 @@ const useWebSocketProviderState = () => { }; const sendMessage = (message) => { - if (ws && isConnected) { - ws.send(JSON.stringify(message)); + const socket = wsRef.current; + if (socket && isConnected) { + socket.send(JSON.stringify(message)); } else { console.warn('WebSocket not connected'); } }; return { - ws, + ws: wsRef.current, sendMessage, messages, isConnected