Skip to main content

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: false to 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 state
    useFetch(
    'live-data',
    () => fetchLiveData(),
    { suspense: true, suspendAfterFirstLoad: false, poll: 5000 }
    );
  • Best Practice: Avoid suspendAfterFirstLoad: true with polling or frequent refetches if you want to prevent UI flickering. If suspendAfterFirstLoad: true, every fetch will trigger the Suspense fallback, leading to a disruptive user experience.
    // Avoid this: Causes loading fallback to flash on every poll
    useFetch(
    '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:

  1. t=0s: Component mounts → No cache exists
  2. useFetch checks: Has data been loaded before? → No (wasLoadedOnce() = false)
  3. useFetch throws Promise → Suspense activates
  4. <LoadingSkeleton /> displays → User sees loading state
  5. t=2s: Fetch completes → Data arrives, cache updated
  6. React re-renders LiveStatsdata has stats, wasLoadedOnce() now true
  7. Stats display on screen → Loading skeleton gone
  8. t=10s: Poll triggers refetchisLoading becomes true
  9. useFetch checks: Has data been loaded before? → Yes (wasLoadedOnce() = true)
  10. useFetch does NOT throw Promise → Suspense stays inactive
  11. Component keeps rendering with old dataisLoading = true shows "● Updating..."
  12. t=12s: Refetch completes → New data arrives, isLoading = false
  13. Component updates smoothly → Stats refresh, no loading skeleton flash

What happens step by step with suspendAfterFirstLoad: true:

  1. t=0s: Component mounts → No cache exists
  2. useFetch throws Promise → Suspense activates
  3. <LoadingSkeleton /> displays → User sees loading state
  4. t=2s: Fetch completes → Data arrives
  5. React re-renders LiveStats → Stats display
  6. t=10s: Poll triggers refetch → Fetch starts
  7. useFetch throws Promise AGAIN → Suspense activates again!
  8. <LoadingSkeleton /> displays again → Loading skeleton flashes every 10 seconds! ⚠️
  9. t=12s: Refetch completes → Data updates
  10. 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

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.