Error: A component suspended while responding to synchronous input. This will cause the UI to be replaced with a loading indicator. To fix, updates that suspend should be wrapped with startTransition.
ID: react/react-suspense-boundary-missing
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| 18 | active | — | — | — |
Root Cause
A React component suspended (threw a Promise) but there is no Suspense boundary ancestor to catch it and show a fallback UI, or a synchronous update caused a suspension that would replace visible content with a fallback. In React 18, components using React.lazy(), data fetching libraries with Suspense support, or the 'use' hook must be wrapped in a <Suspense> boundary. Without it, the thrown Promise propagates as an unhandled error.
genericWorkarounds
-
95% success Add a Suspense boundary with a fallback around components that may suspend
Wrap the suspending component: <Suspense fallback={<LoadingSpinner />}><LazyComponent /></Suspense>. Place Suspense boundaries at meaningful loading boundaries in the UI (e.g., around each route, around each data-dependent section). For React.lazy() components, always wrap them in Suspense. For data fetching with Suspense (e.g., React Query, Relay, use() hook), wrap data-dependent sections. -
88% success Use startTransition for updates that may cause suspension to prevent replacing visible content
Wrap state updates that trigger suspension in startTransition: import { startTransition } from 'react'; startTransition(() => { setResource(newResource); }). This tells React the update is not urgent, so it keeps showing the current UI while the new content loads in the background. The Suspense fallback is only shown if there is no existing content to keep visible. This is essential for tab switches, navigation, and search results.
Dead Ends
Common approaches that don't work:
-
Wrapping the entire application in a single top-level Suspense boundary
55% fail
A single top-level Suspense boundary replaces the entire application UI with a loading indicator whenever any component suspends. This provides a poor user experience because unrelated parts of the UI disappear while one section loads. Suspense boundaries should be placed close to the components that suspend for granular loading states.
-
Converting async data fetching to useEffect + useState to avoid Suspense entirely
50% fail
While this avoids the need for Suspense boundaries, it reintroduces the problems Suspense was designed to solve: loading state management scattered across components, waterfall request patterns, and the need to handle loading/error/success states manually in every component. It also prevents use of React Server Components and streaming SSR.