Recipe
Async Validation
Debounced server-side checks for username, email, and slug availability with loading states and error surfacing.
Pattern
const { status, error } =
useDebouncedAsync(
value,
validateUnique,
400
);The hook fires after a 400ms quiet period. Pending state shows a spinner; resolved state shows a check or cross icon. Errors are surfaced inline beneath the input.
States
- idle — no check triggered
- checking — request in flight
- available — server returned 200
- taken — server returned 409
Endpoint
Expose a GET route at /api/validate?field=username&value=alice. Return 200 for available, 409 for taken. Keep responses under 200 bytes for fast debounce cycles.
Edge Cases
- Cancel in-flight requests when value changes
- Skip validation for empty or unchanged values
- Surface network errors with a distinct retry state
- Rate-limit endpoint to 10 req/s per IP
Next: Optimistic UI patterns →