--- title: "WebSocket React Token Guard" tags: [react, websocket, auth, hooks, javascript] sources: [99 Daily/2026-04-29.md] created: 2026-04-30 updated: 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 ```tsx 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 ```tsx 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 ## Related - [[wiki/concepts/time-sleep-blocks-asyncio|time-sleep-blocks-asyncio]] — another async lifecycle pitfall - [[wiki/tech-patterns/react-patterns|react-patterns]] — React hook conventions