remote-data.tsx
Overview
remote-data.tsx is a React client-side component file that demonstrates the use of SWR (stale-while-revalidate) for fetching remote data asynchronously with React Suspense support. It showcases how to preload data before rendering a component that depends on it, improving the perceived performance and user experience.
The main functionality revolves around:
Using
useSWRwith Suspense mode enabled to fetch data.Preloading the data on demand using
preloadfrom SWR.Conditionally rendering a component inside a React
Suspenseboundary, showing a fallback UI during data loading.
This file serves as a minimal example of integrating SWR's data fetching with React Suspense and preloading capabilities.
Detailed Explanation
Dependencies and Imports
React:
useStatehook for managing local UI state,Suspensecomponent for handling asynchronous loading.SWR: React Hooks library for data fetching with caching, revalidation, and other features.
useSWR: Hook to fetch data.preload: Function to preload data for a given key and fetcher.
Constants and Utility Functions
fetcher
const fetcher = ([key, delay]: [key: string, delay: number]) =>
new Promise<string>(r => {
setTimeout(r, delay, key)
})
Purpose: Simulates a remote fetch request that resolves after a delay.
Parameters:
key: string identifier for the resource.delay: number of milliseconds to wait before resolving.
Returns: A
Promise<string>that resolves to the givenkeystring afterdelayms.Usage: Used as the fetcher function for
useSWR.
key
const key = ['suspense-after-preload', 300] as const
A constant tuple used as the cache key and fetcher argument for SWR.
Represents a unique resource identifier (
'suspense-after-preload') and a 300ms artificial delay.
Hook: useRemoteData
const useRemoteData = () =>
useSWR(key, fetcher, {
suspense: true
})
Wraps
useSWRto fetch the resource identified bykeyusing thefetcher.Suspense mode is enabled (
suspense: true), so React Suspense handles the loading state.Returns: The SWR response object, primarily used here to access
.data.
Component: Demo
const Demo = () => {
const { data } = useRemoteData()
return <div>{data}</div>
}
A simple functional component that consumes the remote data via
useRemoteData.Displays the fetched data inside a
<div>.Because
useRemoteDatais suspense-enabled, this component must be rendered inside a ReactSuspenseboundary to handle the loading state.
Component: Comp
function Comp() {
const [show, toggle] = useState(false)
return (
<div className="App">
<button
onClick={async () => {
preload(key, fetcher)
toggle(!show)
}}
>
preload
</button>
{show ? (
<Suspense fallback={<div>loading</div>}>
<Demo />
</Suspense>
) : null}
</div>
)
}
Main exported component.
Manages local state
show(boolean) to toggle the display of theDemocomponent.Clicking the preload button:
Calls
preload(key, fetcher)to start fetching and caching the data ahead of time.Toggles the
showstate to either mount or unmount theDemocomponent.
When
showistrue, rendersDemoinside a ReactSuspenseboundary with a fallback UI<div>loading</div>.This demonstrates how preloading data reduces or eliminates the loading fallback when the
Democomponent first mounts.
Important Implementation Details
Suspense with SWR:
SWR supports React Suspense by throwing promises internally while fetching.
This allows React to show fallback UI automatically until data resolves.
Preloading:
The
preloadfunction triggers the fetch before the component that uses it renders.Preloaded data is cached, so when
Demomounts, it reads from the cache immediately without delay.
Key as Tuple:
SWR accepts complex keys such as tuples to uniquely identify requests.
Here, the key includes the resource name and the delay parameter, allowing the fetcher to receive this context.
Interaction with Other System Parts
This file is intended as a self-contained React component module.
It depends on the SWR library for data fetching and caching.
It can be integrated into a larger React application where asynchronous data fetching with Suspense is desired.
The pattern demonstrated here can be reused for any remote data resource that benefits from preloading and suspense.
As it uses
'use client'directive, it explicitly runs on client-side rendering in frameworks like Next.js.
Usage Example
To use this component in an application:
import Comp from './remote-data'
function App() {
return (
<div>
<h1>Remote Data Demo</h1>
<Comp />
</div>
)
}
Clicking the preload button fetches data before showing
Demo.When
Demoappears, the data is instantly available due to preloading.If you bypass preloading and render
Demodirectly, React Suspense fallback UI will appear during data fetching.
Mermaid Diagram: Component Interaction and Flow
flowchart TD
A[Comp Component] -->|Button Click| B[preload(key, fetcher)]
B --> C[Cache Data in SWR]
A -->|Toggles show state| D{show ?}
D -->|true| E[Suspense Boundary]
E --> F[Demo Component]
F -->|Calls| G[useRemoteData Hook]
G -->|Uses| H[useSWR with Suspense]
H -->|Fetches with| I[fetcher(key, delay)]
I -->|Returns Promise resolving after delay| C
E -->|fallback| J[Loading UI]
Summary
remote-data.tsx is a concise demonstration of integrating SWR's data fetching with React Suspense and preloading. It features:
A mock async fetcher with delay simulation.
A suspense-enabled SWR hook for data fetching.
Preloading data on button click before rendering.
Conditional rendering with Suspense fallback for loading states.
This pattern is useful for improving UX in React applications that deal with asynchronous data by minimizing loading flickers and enabling seamless data transitions.