---
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
