From harness-claude
Declaratively handles async loading states using React Suspense boundaries for lazy-loading components and data fetching with libraries like React Query or SWR in React 18+ apps.
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeThis skill uses the workspace's default tool permissions.
> Declaratively handle async loading states with React Suspense boundaries
Enables TanStack Query suspense mode via useSuspenseQuery to suspend React components on data load instead of inline loading states, for Suspense boundaries and Next.js App Router streaming.
Provides React UI patterns for loading states, error handling, and data fetching including skeletons, optimistic updates, decision trees, and error hierarchies. Use for async UI components.
Provides React 19 patterns for use() hook, Server Components, Server Actions, useActionState, useOptimistic, and Suspense with Next.js examples.
Share bugs, ideas, or general feedback.
Declaratively handle async loading states with React Suspense boundaries
React.lazy() — Suspense is requireduseEffect<Suspense fallback={<LoadingUI />}>.<ErrorBoundary> to handle promise rejections.React.lazy(() => import('./Component')).const HeavyChart = React.lazy(() => import('./HeavyChart'));
function Dashboard() {
return (
<ErrorBoundary fallback={<p>Failed to load chart</p>}>
<Suspense fallback={<ChartSkeleton />}>
<HeavyChart />
</Suspense>
</ErrorBoundary>
);
}
Suspense works by components "throwing" a promise when they are not ready. React catches the promise at the nearest Suspense boundary and renders the fallback until the promise resolves.
React 18 changes: startTransition lets you mark state updates as non-urgent, preventing Suspense fallbacks from showing for fast transitions (the previous content stays visible until the new content is ready).
Library support: Not all data-fetching approaches support Suspense. Use libraries that explicitly support it (useSuspenseQuery in React Query, use() hook in React 18+ with compatible data sources).
Common mistake: Placing the Suspense boundary too high (at the page level) shows a full-page spinner for small widget loads. Granular boundaries improve perceived performance.
https://patterns.dev/react/suspense-pattern