Race Condition Handling
Race conditions occur when the order of async operations affects correctness. React Router automatically prevents the most common UI race conditions.What React Router Prevents
React Router handles race conditions in:- Navigation: Interrupted navigations are cancelled
- Form submissions: Interrupted submissions are cancelled
- Revalidation: Stale revalidations are discarded
- Fetcher requests: Self-interrupting requests are cancelled
Browser-Inspired Behavior
React Router mirrors browser behavior:Link Navigation
Browser: Click Link A, then Link B before A loads → A is cancelled, B proceeds React Router: Same behavior with client-side routingForm Submission
Browser: Submit Form A, then Form B before A completes → A is cancelled, B proceeds React Router: Same behavior with Form componentsNavigation Race Conditions
Problem: Stale Navigation
Without cancellation, slow requests could overwrite newer navigations:Solution: Automatic Cancellation
React Router cancels in-flight requests:Revalidation Race Conditions
Problem: Out-of-Order Revalidation
Multiple actions can trigger overlapping revalidations:Solution: Discard Stale Revalidation
React Router tracks request timing:Fetcher Race Conditions
Self-Interrupting Fetchers
Fetchers cancel their own previous requests:Independent Fetchers
Different fetcher instances don’t cancel each other:Type-Ahead Search Example
Common race condition scenario:Solution
React Router automatically cancels:Optimistic UI Race Conditions
Problem: Failed Optimistic Updates
Solution: Revert on Error
Server Race Conditions
React Router only prevents client race conditions. Server race conditions require server-side solutions.Problem: Backend Race Condition
Solutions
Optimistic Locking:Request Abortion
Detect when requests are cancelled:Polling Race Conditions
Problem: Overlapping Polls
Solution: Wait for Completion
Testing Race Conditions
Simulate race conditions in tests:Best Practices
- Trust automatic cancellation: React Router handles it
- Handle server race conditions: Use locks, timestamps, or tokens
- Revert optimistic failures: Show error and original state
- Pass abort signals: To fetch() for proper cleanup
- Test rapid interactions: Simulate race conditions
What React Router Doesn’t Prevent
❌ Server-side race conditions❌ Race conditions between different apps
❌ WebSocket message ordering
❌ Browser storage conflicts