Skip to main content

react

Core skill for @suspensive/react: Suspense (clientOnly prop), ErrorBoundary (fallback, shouldCatch, resetKeys, onError, onReset), ErrorBoundaryGroup, Delay, ClientOnly, useIsClient, useErrorBoundary, useErrorBoundaryFallbackProps, DefaultPropsProvider/DefaultProps, lazy/createLazy/reloadOnError, and the shared .with() HOC pattern. Load when code imports '@suspensive/react' or needs declarative Suspense boundaries, error boundaries, loading fallbacks, or client-only rendering in React 18+.

Quellinformationen

Repository
toss/suspensive
Letzte Quellaktivität
4. Juli 2026 um 07:04
Erkannte Sprache von SKILL.md
Englisch
Sterne
1.059
Forks
99

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
5 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
react
description
Core skill for @suspensive/react: Suspense (clientOnly prop), ErrorBoundary (fallback, shouldCatch, resetKeys, onError, onReset), ErrorBoundaryGroup, Delay, ClientOnly, useIsClient, useErrorBoundary, useErrorBoundaryFallbackProps, DefaultPropsProvider/DefaultProps, lazy/createLazy/reloadOnError, and the shared .with() HOC pattern. Load when code imports '@suspensive/react' or needs declarative Suspense boundaries, error boundaries, loading fallbacks, or client-only rendering in React 18+.
metadata
{"type":"core","library":"@suspensive/react","library_version":"3.21.2","framework":"react"}
sources
["toss/suspensive:docs/suspensive.org/src/content/en/docs/react/motivation.mdx","toss/suspensive:packages/react/src/index.ts"]
# @suspensive/react `@suspensive/react` provides declarative components and hooks that fill gaps in React's built-in Suspense, error boundary, and lazy primitives. Runtime exports: `Suspense`, `ErrorBoundary`, `ErrorBoundaryGroup`, `Delay`, `ClientOnly`, `DefaultPropsProvider`, `DefaultProps`, `lazy`, `createLazy`, `reloadOnError`, `useErrorBoundary`, `useErrorBoundaryFallbackProps`, `useErrorBoundaryGroup`, `useIsClient`. Type exports: `SuspenseProps`, `ErrorBoundaryProps`, `ErrorBoundaryFallbackProps`, `ErrorBoundaryGroupProps`, `DelayProps`, `ClientOnlyProps`. Requires React >= 18 (native `useSyncExternalStore`). Every component (`Suspense`, `ErrorBoundary`, `ErrorBoundaryGroup`, `Delay`, `ClientOnly`) exposes a static `.with(props, Component)` HOC that wraps `Component` with that boundary. > **CRITICAL**: All Suspensive components are client components (`'use client'`). Never render them directly in a React Server Component — render-prop children are functions, which cannot cross the RSC serialization boundary. Put them inside a component marked `'use client'`. > **CRITICAL**: These APIs were removed and must never be generated: the `wrap` builder (`wrap.ErrorBoundary(...).Suspense(...).on(...)`, removed in v3 — use `.with()`), `AsyncBoundary` and the `withSuspense`/`withDelay`/`withErrorBoundary`/`withErrorBoundaryGroup` HOCs (removed in v2 — compose `ErrorBoundary` + `Suspense` or use `.with()`), `Suspense.CSROnly` (removed in v2 — use the `clientOnly` prop), and `ErrorBoundaryGroup.Reset` (removed in v2 — use `ErrorBoundaryGroup.Consumer`). Agents trained on older code still generate all of these. See [migrate-to-v3](../lifecycle/migrate-to-v3/SKILL.md). > **CRITICAL**: The component returned by `.with()` rejects extra static properties (router `loader`s etc.) at the type level. Attach statics with `Object.assign(Suspense.with(props, Component), { loader })`, not direct assignment. ## Sub-Skills | Task | Skill | | -------------------------------------------------------------------------- | ---------------------------------------------------- | | Catch specific error types, reset one or many boundaries, fallback props | [error-handling](./error-handling/SKILL.md) | | Suspense fallbacks, prevent flash-of-loading with Delay, app-wide defaults | [loading-ux](./loading-ux/SKILL.md) | | Skip SSR per boundary, hydration-safe client detection | [ssr-client-only](./ssr-client-only/SKILL.md) | | Preload lazy components, recover from chunk-load failures after deploys | [code-splitting](./code-splitting/SKILL.md) | | Upgrade from v1/v2 (`wrap`, `AsyncBoundary`, `with*` HOCs, codemods) | [migrate-to-v3](../lifecycle/migrate-to-v3/SKILL.md) | ## Quick Decision Tree ``` Need to... ├─ catch render errors / filter by error type / reset boundaries │ → error-handling (ErrorBoundary, shouldCatch, ErrorBoundaryGroup) ├─ show a loading fallback / avoid a 50ms spinner flash / set one default fallback │ → loading-ux (Suspense, Delay, DefaultPropsProvider) ├─ skip SSR for a subtree / read browser APIs without hydration mismatch │ → ssr-client-only (Suspense clientOnly, ClientOnly, useIsClient) ├─ code-split with preloading / survive stale-chunk errors after a deploy │ → code-splitting (lazy, createLazy, reloadOnError) └─ upgrade code that uses wrap / AsyncBoundary / withSuspense / Suspense.CSROnly → migrate-to-v3 (codemods, old→new API table) ``` ## Minimal Working Example ```tsx 'use client' import { Delay, ErrorBoundary, Suspense } from '@suspensive/react' import { UserProfile } from './UserProfile' export const UserSection = () => ( <ErrorBoundary fallback={({ error, reset }) => ( <div> <p>{error.message}</p> <button onClick={reset}>Try again</button> </div> )} > <Suspense fallback={ <Delay ms={200}> <div>Loading...</div> </Delay> } > <UserProfile /> </Suspense> </ErrorBoundary> ) ``` The same tree with the `.with()` HOC pattern: ```tsx 'use client' import { ErrorBoundary, Suspense } from '@suspensive/react' import { UserProfile } from './UserProfile' export const UserSection = ErrorBoundary.with( { fallback: ({ error }) => <p>{error.message}</p> }, Suspense.with({ fallback: <div>Loading...</div> }, () => <UserProfile />) ) ``` ## Common Mistakes ### HIGH Rendering Suspensive components in a Server Component Wrong: ```tsx // app/page.tsx — Server Component import { Suspense } from '@suspensive/react' export default function Page() { return ( <Suspense fallback={<div>Loading...</div>}> <Content /> </Suspense> ) } ``` Correct: ```tsx // app/page.tsx — Server Component import { ContentSection } from './ContentSection' export default function Page() { return <ContentSection /> } ``` ```tsx // ContentSection.tsx 'use client' import { Suspense } from '@suspensive/react' import { Content } from './Content' export const ContentSection = () => ( <Suspense fallback={<div>Loading...</div>}> <Content /> </Suspense> ) ``` All Suspensive components are client-only (`'use client'`), so using them directly in an RSC fails the build or errors at render. Source: https://github.com/toss/suspensive/issues/1563 ### MEDIUM Attaching static properties to .with() result directly Wrong: ```tsx import { Suspense } from '@suspensive/react' const Page = Suspense.with({ fallback: <div>Loading...</div> }, PageComponent) Page.loader = loader // type error export default Page ``` Correct: ```tsx import { Suspense } from '@suspensive/react' export default Object.assign(Suspense.with({ fallback: <div>Loading...</div> }, PageComponent), { loader }) ``` The component type returned by `.with()` rejects extra static properties, so router loaders and similar statics must be merged with `Object.assign`. Source: https://github.com/toss/suspensive/issues/1665 ## Version Targets `@suspensive/react` v3.21.2. Requires React >= 18.0.
Auf GitHub ansehen