본문으로 건너뛰기
cccskills
무료GitHub에 공개

web-framework-react

Component architecture, hooks and React 19 patterns. Load when building or refactoring React components, custom hooks, forms, or async UI.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(6)

  • SKILL.md9.5 KB
  • examples/core.md6.2 KB
  • examples/hooks.md4.3 KB
  • examples/react-19-hooks.md10.6 KB
  • metadata.yaml395 B
  • reference.md3.8 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

React Patterns

Quick Guide: React 19 settles four things this skill turns on — ref is a regular prop and forwardRef is redundant, form submission state comes from useActionState, useFormStatus reads the enclosing form only from a child component, and a ref callback may return a cleanup function. Components stay styling-agnostic by exposing className and expressing variants as data-* attributes.

Detailed Resources:


Which path applies

  • React rendered in the browser — every pattern below applies as written, and form submission goes through useActionState in examples/react-19-hooks.md.
  • React rendered by a server framework — submission and data loading belong to that framework's own server primitives, so skip Pattern 6 and take the component, hook, ref and error-boundary patterns unchanged.

<critical_requirements>

Before writing React code

Pass ref as a regular prop. React 19 forwards it without forwardRef, which removes the wrapper and the manual displayName.

Expose className on every reusable component. It is the one seam a consumer has for styling a component this skill knows nothing about.

Call useFormStatus from a component rendered inside the <form>. Called in the component that renders the form it returns pending: false forever, with no error to show for it.

Reach for useActionState when a form needs pending or error state. It carries both, and <form action={...}> keeps working before hydration.

</critical_requirements>


Auto-detection: React 19, useActionState, useFormStatus, useOptimistic, use(), ref as prop, ref cleanup, forwardRef migration, React.ComponentProps, getDerivedStateFromError, componentDidCatch, useCallback, custom hook

Applies to:

  • Component props, composition and variant APIs
  • Migrating forwardRef components to ref-as-prop
  • Form submission, optimistic updates and promise reading with the React 19 hooks
  • Custom hooks for reusable stateful logic
  • Error boundaries with retry

Handled elsewhere:

  • Styling — a component takes className and exposes variants as data-*; which CSS approach fills them in is not its concern
  • Client state that outlives a component, and server data with its caching and invalidation — components receive both as props and stay unaware of the source
  • Routing, and the data a route loads
  • Test doubles for the network

<patterns>

Core patterns

Pattern 1: Component shape

A reusable component spreads its element's own props, accepts ref directly, and expresses variants as data-* attributes any styling layer can target.

export type ButtonProps = React.ComponentProps<"button"> & {
  variant?: "default" | "ghost" | "link";
  size?: "default" | "large" | "icon";
  ref?: React.Ref<HTMLButtonElement>;
};

export function Button({ variant = "default", size = "default", className, ref, ...props }: ButtonProps) {
  return <button className={className} data-variant={variant} data-size={size} ref={ref} {...props} />;
}

Full code: examples/core.md


Pattern 2: Typed variant props

Give a component variant props once it has two or more visual dimensions. A component with one visual style takes className and nothing else — a union with a single member is an abstraction with no second case.

export type AlertVariant = "info" | "warning" | "error" | "success";

export function Alert({ variant = "info", className, ref, ...props }: AlertProps) {
  return <div ref={ref} className={className} data-variant={variant} {...props} />;
}

Full code: examples/core.md


Pattern 3: Event handler naming

handle prefixes an internal handler (handleNameChange), on prefixes a callback prop (onSelect), and each handler types its event — FormEvent<HTMLFormElement>, ChangeEvent<HTMLInputElement> — so a wrong field access fails at compile time.

Full code: examples/core.md


Pattern 4: Custom hooks

Logic that calls hooks and renders nothing is a use-prefixed hook rather than a component: pagination state, debounced values, persisted preferences.

Full code: examples/hooks.md


Pattern 5: Error boundaries with retry

A boundary catches render errors and hands back a reset function, so a transient failure costs one section rather than the page. Place one around each feature area, not only the root.

interface Props {
  children: ReactNode;
  fallback?: (error: Error, reset: () => void) => ReactNode;
  onError?: (error: Error, errorInfo: ErrorInfo) => void;
}

A boundary is a class because there is no hook form of getDerivedStateFromError. Placement, recovery and fallback design are a subject of their own and are settled outside this skill.


Pattern 6: useActionState for form submission

The hook returns the action's last result, the action to hand <form action={...}>, and a pending flag — replacing three useState calls and their reset logic.

async function updateProfile(prevState: string | null, formData: FormData) {
  try {
    await saveProfile({ name: formData.get("name") as string });
    return null;
  } catch {
    return "Failed to save profile";
  }
}

const [error, submitAction, isPending] = useActionState(updateProfile, null);

Full code: examples/react-19-hooks.md


Pattern 7: useFormStatus for submit buttons

A submit button reads the enclosing form's pending state itself, so one button component serves every form and no form passes the flag down.

import { useFormStatus } from "react-dom";

function SubmitButton({ children }: { children: React.ReactNode }) {
  const { pending } = useFormStatus();
  return (
    <button type="submit" disabled={pending} aria-busy={pending}>
      {pending ? "Submitting..." : children}
    </button>
  );
}

Full code: examples/react-19-hooks.md


Pattern 8: useOptimistic for instant feedback

Render the expected result immediately and let React revert it if the request fails. The setter is called inside startTransition.

const [optimisticItems, addOptimistic] = useOptimistic(
  items,
  (state, update: Item) => [...state, { ...update, pending: true }],
);

startTransition(async () => {
  addOptimistic(newItem);
  await saveItem(newItem);
});

Full code: examples/react-19-hooks.md


Pattern 9: use() for promises and context

use() reads a promise or a context during render and, unlike useContext, may be called after an early return. A promise suspends until it resolves, so the caller sits under <Suspense> and a rejection is caught by an error boundary.

function Comments({ commentsPromise }: { commentsPromise: Promise<Comment[]> }) {
  const comments = use(commentsPromise);
  return <ul>{comments.map((c) => <li key={c.id}>{c.text}</li>)}</ul>;
}

<Suspense fallback={<p>Loading...</p>}>
  <Comments commentsPromise={fetchComments()} />
</Suspense>

Full code: examples/react-19-hooks.md


Pattern 10: Ref callback cleanup

A ref callback may return a cleanup function, which runs on unmount — replacing the useRef + useEffect pair for DOM setup.

<video
  ref={(video) => {
    if (!video) return;
    video.play();
    return () => {
      video.pause();
      video.currentTime = 0;
    };
  }}
  src={src}
/>

Full code: examples/react-19-hooks.md

</patterns>

<red_flags>

Red flags

Breaks at runtime:

  • useFormStatus called in the component that renders <form> — pending stays false and the button never disables; call it from a child
  • use() inside try/catch — it throws to suspend, so the catch swallows the suspension; wrap the caller in an error boundary instead
  • The useOptimistic setter called outside a transition or a form action — React rejects the call, so the optimistic value never lands
  • Browser APIs read during render under SSR — guard with typeof window !== "undefined" or move the read into an effect
  • An error boundary relied on for event-handler, async or SSR errors — it catches render errors only, so those paths carry their own try/catch

Surprising behaviour:

  • A ref callback returning anything but a cleanup function is a type error in React 19, and the callback is no longer called with null on unmount
  • useOptimistic reverts on failure by itself, so a manual rollback fights it
  • useCallback around a handler passed to a child that is not memoised costs an allocation and buys nothing; the React Compiler makes the wrapper redundant either way
  • forwardRef still compiles, so nothing flags the wrapper and its displayName as dead weight
  • A component without className cannot be styled by its consumer at all

</red_flags>

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Hugging Face Inference SDK patterns for TypeScript/Node.js — InferenceClient setup, chat completion, text generation, streaming, embeddings, image generation, audio transcription, translation, summarization, and Inference Endpoints

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

agents-inc/skills252026년 10월 17일 업데이트

LiteLLM proxy server setup, TypeScript client patterns via OpenAI SDK, model routing, fallbacks, load balancing, spend tracking, virtual keys, and production deployment

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

agents-inc/skills252026년 10월 17일 업데이트

Serverless GPU compute platform for AI model deployment — web endpoints, GPU functions, model serving, and TypeScript client patterns

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

agents-inc/skills252026년 10월 17일 업데이트

Local LLM inference with the Ollama JavaScript client -- chat, streaming, tool calling, vision, embeddings, structured output, model management, and OpenAI-compatible endpoint

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

agents-inc/skills252026년 10월 17일 업데이트

Replicate SDK patterns for TypeScript/Node.js -- client setup, predictions, streaming, webhooks, file handling, model versioning, deployments, and training

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

agents-inc/skills252026년 10월 17일 업데이트

Together AI SDK patterns for TypeScript — client setup, chat completions, streaming, structured output, function calling, embeddings, image generation, fine-tuning, and OpenAI-compatible endpoints

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

agents-inc/skills252026년 10월 17일 업데이트

agents-inc의 스킬 모두 보기

이 스킬의 문제 신고