Manual Retry UI
Purpose
This subtopic addresses the need for a clear and user-friendly mechanism to manually retry data fetching operations within React applications using SWR. While automatic retry strategies (such as exponential backoff) handle transient errors behind the scenes, certain scenarios require explicit user intervention to trigger retries—especially when using React Suspense and error boundaries to manage asynchronous data and error states.
The Manual Retry UI pattern provides a structured way to:
Catch and display errors during data fetching.
Offer users a retry button to initiate a fresh fetch attempt.
Integrate gracefully with Suspense to manage loading states.
Reset error boundaries to recover from errors.
This ensures robust UX by empowering users to recover from errors without full page reloads or complex state management.
Functionality
The core workflow involves three components working in tandem:
Data Fetching Hook with Suspense Support
A hook (e.g.,useRemoteData) usesuseSWRwith suspense enabled to fetch remote data. If the fetch fails, React Suspense suspends rendering, and the error boundary catches the error.Error Boundary with Fallback UI
TheErrorBoundarycomponent from the react-error-boundary library catches errors thrown during render or lifecycle phases—including those from suspended data fetching. Its fallback UI displays an error message and a retry button.Retry Mechanism Triggered by User Action
When the retry button is clicked, it invokes a function to reset the error boundary and revalidate the data. This can be done by either:Calling a preload function to prime the cache before resetting the error boundary.
Using SWR's
mutatefunction to trigger a cache mutation and re-fetch.
Key Code Interactions
Data Hook with Suspense:
const useRemoteData = () => useSWR(key, fetcher, { suspense: true })This hook suspends rendering until data is fetched or an error occurs.
Fallback Component with Retry Button:
function Fallback({ resetErrorBoundary }: any) { return ( <div role="alert"> <p>Something went wrong</p> <button onClick={() => resetErrorBoundary()}> retry </button> </div> ) }The
resetErrorBoundarycall clears the error state, allowing a retry.Manual Mutation Trigger on Retry:
<button onClick={async () => { await mutate(key, fetcher) resetErrorBoundary() }} > retry </button>This triggers a fresh fetch before resetting the error boundary to avoid immediate fallback.
Integration with Parent Topic and Other Subtopics
Manual Retry UI is a concrete implementation pattern that complements the broader error handling and retry logic mechanisms within the project. While the parent topic defines configurable retry strategies such as exponential backoff and automated retries, Manual Retry UI focuses on explicit user-driven retry control integrated with Suspense and error boundaries.
It leverages foundational features from the core SWR hook (useSWR with suspense) and interacts with retry strategies by providing a manual override. This subtopic also connects with data preloading concepts by optionally preloading data during retry to improve perceived performance.
Together with other subtopics like Retry Strategy and Error Handling, Manual Retry UI forms a holistic approach to resilient data fetching that balances automation with user control.
Diagram
flowchart TD
A[Component Mounts] --> B[useRemoteData Hook Fetches Data]
B -->|Fetch Succeeds| C[Render Data]
B -->|Fetch Fails| D[Error Thrown]
D --> E[ErrorBoundary Catches Error]
E --> F[Fallback UI with Retry Button]
F -->|Retry Clicked| G[Trigger SWR Mutate or Preload]
G --> H[Reset Error Boundary]
H --> B
This flowchart illustrates the lifecycle of data fetching with manual retry, showing how the error boundary and retry button coordinate with SWR's mutation or preloading to recover from errors seamlessly.