suspendAfterFirstLoad
Description: Defines if the component should suspend when fetching data after the initial load (e.g. during refetches).
Default Value: true.
- How To: Use
suspendAfterFirstLoad: falseto ensure that only the initial fetch triggers a Suspense fallback, while subsequent background updates (like polling or refetches) happen seamlessly without re-suspending the UI. This provides a smooth user experience for dynamic data.// Correct: Only the first load will show a full loading stateuseFetch('live-data',() => fetchLiveData(),{ suspense: true, suspendAfterFirstLoad: false, poll: 5000 }); - Best Practice: Avoid
suspendAfterFirstLoad: truewith polling or frequent refetches if you want to prevent UI flickering. IfsuspendAfterFirstLoad: true, every fetch will trigger the Suspense fallback, leading to a disruptive user experience.// Avoid this: Causes loading fallback to flash on every polluseFetch('live-data',() => fetchLiveData(),{ suspense: true, suspendAfterFirstLoad: true, poll: 5000 } // BAD: Suspends every time data is fetched);
Deep Dive: How suspendAfterFirstLoad works step by step
Example:
function LiveStats() {
const { data, isLoading } = useFetch(
'stats', // The fetch key
() => fetchStats(),
{ suspense: true, suspendAfterFirstLoad: false, poll: 10000 } // Options
);
return (
<div>
{isLoading && <span>● Updating...</span>}
<StatsDisplay data={data} />
</div>
);
}
<Suspense fallback={<LoadingSkeleton />}>
<LiveStats />
</Suspense>
What happens step by step with suspendAfterFirstLoad: false:
- t=0s: Component mounts → No cache exists
useFetchchecks: Has data been loaded before? → No (wasLoadedOnce() = false)useFetchthrows Promise → Suspense activates<LoadingSkeleton />displays → User sees loading state- t=2s: Fetch completes → Data arrives, cache updated
- React re-renders
LiveStats→datahas stats,wasLoadedOnce()nowtrue - Stats display on screen → Loading skeleton gone
- t=10s: Poll triggers refetch →
isLoadingbecomestrue useFetchchecks: Has data been loaded before? → Yes (wasLoadedOnce() = true)useFetchdoes NOT throw Promise → Suspense stays inactive- Component keeps rendering with old data →
isLoading = trueshows "● Updating..." - t=12s: Refetch completes → New data arrives,
isLoading = false - Component updates smoothly → Stats refresh, no loading skeleton flash
What happens step by step with suspendAfterFirstLoad: true:
- t=0s: Component mounts → No cache exists
useFetchthrows Promise → Suspense activates<LoadingSkeleton />displays → User sees loading state- t=2s: Fetch completes → Data arrives
- React re-renders
LiveStats→ Stats display - t=10s: Poll triggers refetch → Fetch starts
useFetchthrows Promise AGAIN → Suspense activates again!<LoadingSkeleton />displays again → Loading skeleton flashes every 10 seconds! ⚠️- t=12s: Refetch completes → Data updates
- Stats display again → But user saw disruptive loading flash
Key difference: suspendAfterFirstLoad: false only suspends on the very first load. All subsequent fetches (refetches, polls) update silently in the background. suspendAfterFirstLoad: true suspends on every fetch, causing UI flashing.
Note that isLoading is typically always false when suspense: true because the component suspends (throws a Promise) before it can return isLoading: true. However, when using suspendAfterFirstLoad: false, isLoading will be true during subsequent background fetches (refetches/polling) because the component no longer suspends after the initial load.