obsidian/wiki/concepts/websocket-react-token-guard.md
2026-04-30 21:18:40 +01:00

2.1 KiB

title tags sources created updated
WebSocket React Token Guard
react
websocket
auth
hooks
javascript
99 Daily/2026-04-29.md
2026-04-30 2026-04-30

WebSocket React Token Guard

A React useEffect that opens a WebSocket connection must guard against a null/undefined auth token. Without the guard, the socket opens immediately (before auth resolves), the server rejects the handshake, and the socket closes — leaving the UI in a broken state with no obvious error.

The Bug

useEffect(() => {
  const ws = new WebSocket(`wss://api.example.com/ws?token=${token}`);
  // token is null on first render — ws opens with "token=null", server closes it
  ws.onmessage = (e) => setData(JSON.parse(e.data));
  return () => ws.close();
}, []);  // ← missing token in dep array; never reconnects after login

Two mistakes:

  1. No early return when token is null or undefined
  2. token not in the dependency array — even if auth eventually resolves, the effect never re-runs

Fixed Pattern

useEffect(() => {
  if (!token) return;  // ← guard: do nothing until auth is ready

  const ws = new WebSocket(`wss://api.example.com/ws?token=${token}`);
  ws.onmessage = (e) => setData(JSON.parse(e.data));

  return () => ws.close();  // cleanup closes previous socket on token change
}, [token]);  // ← re-runs when token appears or changes

Why Both Changes Are Required

Fix Without it
if (!token) return Socket opens with token=null → server rejects → immediate close
token in dep array Socket never reconnects after login because effect only ran once (with null token)

Lifecycle on First Render

  1. Component mounts, token is null → effect runs → if (!token) return exits early
  2. Auth resolves, token is set → React re-runs effect because token is a dep
  3. Effect runs again with a valid token → socket opens and stays open