← back to Dw Boardroom Governance
Fix useWebSocket: prevent zombie reconnect timer firing after component unmount
44b2fa89fc34e939a20719d5dff8b9d265dfa2b0 · 2026-05-18 20:17:51 -0700 · Steve Abrams
Files touched
M frontend/src/hooks/useWebSocket.ts
Diff
commit 44b2fa89fc34e939a20719d5dff8b9d265dfa2b0
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Mon May 18 20:17:51 2026 -0700
Fix useWebSocket: prevent zombie reconnect timer firing after component unmount
---
frontend/src/hooks/useWebSocket.ts | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/frontend/src/hooks/useWebSocket.ts b/frontend/src/hooks/useWebSocket.ts
index dcce50d..db3eb08 100644
--- a/frontend/src/hooks/useWebSocket.ts
+++ b/frontend/src/hooks/useWebSocket.ts
@@ -9,13 +9,16 @@ export function useWebSocket() {
useEffect(() => {
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
const wsUrl = `${protocol}//${window.location.host}/ws`;
+ let cancelled = false;
+ let reconnectTimer: ReturnType<typeof setTimeout> | null = null;
function connect() {
+ if (cancelled) return;
const ws = new WebSocket(wsUrl);
wsRef.current = ws;
ws.onopen = () => {
- setConnected(true);
+ if (!cancelled) setConnected(true);
};
ws.onmessage = (e) => {
@@ -26,8 +29,9 @@ export function useWebSocket() {
};
ws.onclose = () => {
+ if (cancelled) return;
setConnected(false);
- setTimeout(connect, 3000);
+ reconnectTimer = setTimeout(connect, 3000);
};
ws.onerror = () => {
@@ -38,7 +42,10 @@ export function useWebSocket() {
connect();
return () => {
+ cancelled = true;
+ if (reconnectTimer) clearTimeout(reconnectTimer);
if (wsRef.current) {
+ wsRef.current.onclose = null;
wsRef.current.close();
}
};
← 79f893e Harden basic-auth middleware: timing-safe compare, malformed
·
back to Dw Boardroom Governance
·
Add error handling to frontend API mutation handlers to prev 83b5830 →