JWT Token Refresh Patterns in React 19: Avoiding the Silent Auth Death Spiral
I've watched authentication break in production more times than I want to admit. Usually it's silent—users get logged out mid-action, requests fail with 401s, and nobody notices until support tickets pile up. The culprit? Naive token refresh logic that doesn't handle concurrent requests.
Most solutions I see are either bloated (Redux middleware with retry queues) or fragile (localStorage checks that fail when two requests hit simultaneously). I'm going to show you the approach I use in CitizenApp: minimal, correct, and battle-tested with concurrent traffic.
The Problem: Why Simple Token Refresh Fails
Let me paint a scenario. User opens your app. Token expires. They click a button that triggers three API calls simultaneously. Here's what happens with naive refresh:
// ❌ Bad: Each request independently tries to refresh async function apiCall ( endpoint : string ) { let token = localStorage .…