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+.

소스 정보

저장소
toss/suspensive
최근 소스 활동
2026년 7월 4일 07:04
감지된 SKILL.md 언어
영어
스타
1,059
포크
99

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

파일 탐색기
5 개 파일

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
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.
GitHub에서 보기