К основному содержанию
скилл CX Codex

react-dev — скилл для Claude Code: что делает и как установить

Скилл помогает писать строго типизированный код на React 18–19 и переходить на новые API вроде useActionState.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add softaworks/agent-toolkit --skill react-dev -a claude-code
Открыть на GitHub

Что делает react-dev

Скилл добавляет в контекст ассистента правила типизации компонентов, хуков и событий React на TypeScript. Внутри собраны готовые шаблоны для generic-компонентов, дискриминированных объединений в пропсах и точной привязки событий мыши или клавиатуры.

Отдельный блок посвящён изменениям React 19: отказу от forwardRef в пользу обычного пропса ref, замене useFormState на хук useActionState, вызову use() для промисов и асинхронным Server Components с директивой 'use server'. Также учтены примеры для TanStack Router и React Router.

Этот скилл бесполезен в проектах на чистом JavaScript или в коде без React. Для работы нужен именно TypeScript-стек, иначе ассистент будет навязывать лишние типы там, где они не поддержаны сборщиком.

Какие задачи решает

  • типизировать generic-компоненты и render-пропсы без any
  • переписать устаревший forwardRef на обычный ref в React 19
  • настроить useActionState и серверные экшены со строгими типами
  • задать точные типы для обработчиков событий ввода и отправки форм

Примеры запросов агенту

  • Напиши типизированную таблицу на React 19 с пропсами через generics
  • Перепиши этот компонент формы с useFormState на useActionState
  • Сделай кастомный хук useToggle с возвратом кортежа через as const

Как установить react-dev

1Через Skills CLI (Vercel)

npx skills add softaworks/agent-toolkit --skill react-dev -a claude-code

2Вручную: положить файлы

~/.claude/skills/react-dev/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/react-dev/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Из того же набора12

database-schema-designer Скилл проектирует схемы для SQL и NoSQL, продумывает связи, ограничения, индексы и миграции. Пригодится при создании или пересмотре модели данных. CX Codex +1 4 300установок qa-test-planner Собирает тест-план, ручные тест-кейсы, регрессионный набор и баг-репорт по описанию фичи. Запускается только по имени: qa-test-planner. CX Codex +1 4 300установок session-handoff Создаёт документы передачи контекста между сессиями агента. Помогает при переполнении окна контекста и долгих проектах. CX Codex +1 4 200установок codex Скилл запускает Codex CLI для анализа, рефакторинга и автоматического редактирования кода. По умолчанию использует GPT-5.2 с адаптивным reasoning и достигает 76.3% на SWE-bench. CX Codex +1 4 100установок feedback-mastery Структурирует подготовку к сложным разговорам и разбор рабочих конфликтов по моделям SBI и Preparation-Delivery-Follow-up. Помогает составить фактологический фидбек. CX Codex +1 4 000установок gemini Скилл учит агента запускать Gemini CLI для ревью кода, разбора архитектурного плана и файлов, которые не влезают в контекст. Пригодится, когда нужно второе мнение по всему репозиторию. CX Codex +1 4 000установок reducing-entropy Скилл, который мерит успех итоговым объёмом кода, а не потраченными усилиями. Вызывается вручную и режет проект, пока тот не станет меньше. CX Codex +1 4 000установок plugin-forge Скилл для создания и управления плагинами Claude Code с правильной структурой, манифестами и интеграцией маркетплейса. Нужен, если вы собираете плагины для распространения или настраиваете компоненты команд и хуков. CX Codex +1 3 900установок

Похожие

react-expert https://github.com/Jeffallan Скилл для разработки на React 18+, Next.js App Router и create-react-app. Генерирует компоненты, хуки, чинит рендер и переводит классовые компоненты на функциональные. CX Codex +1 5 500установок react-patterns giuseppe-trisciuoglio Подсказывает агенту паттерны React 19: Server Components, Server Actions, useOptimistic, Suspense. Пригодится, когда пишете приложение на Next.js App Router. CX Codex +1 4 800установок react-19 prowler-cloud Скилл для работы с React 19 и React Compiler: без ручной мемоизации, серверные компоненты первыми, ref как проп. CX Codex +1 671установок react pproenca Скилл с 49 правилами React 19 и алгоритмом ревью кодовой базы. Пригодится при написании компонентов, миграции с React 18 и аудите репозитория. CX Codex +1 489установок nextjs-architecture-expert davila7 Субагент для Claude, который разбирает архитектуру Next.js: App Router, Server Components, миграцию и производительность. 4 935установок laravel-inertia-react AsyrafHussin Скилл с готовыми правилами для страниц Inertia, форм на useForm и общих данных в связке Laravel и React. CX Codex +1 1 900установок

Рядом в теме «Фронтенд и UI»

Всё по теме «Фронтенд и UI» →

Вопросы о react-dev

Как установить react-dev в Claude Code?

Выполните команду npx skills add softaworks/agent-toolkit --skill react-dev -a claude-code. Ассистент сразу подхватит инструкции.

Для каких проектов подходит скилл?

Он рассчитан на кодовые базы с React 18 или React 19 на TypeScript. Для чистого JavaScript или бекенд-задач вне React эти инструкции не подходят.

Какие особенности React 19 учитывает react-dev?

Скилл описывает отказ от forwardRef ради передачи ref напрямую, замену useFormState хуком useActionState, работу с use() и типизацию асинхронных Server Components.

Исходный текст

SKILL.md · MIT
---
name: react-dev
version: 1.0.0
description: This skill should be used when building React components with TypeScript, typing hooks, handling events, or when React TypeScript, React 19, Server Components are mentioned. Covers type-safe patterns for React 18-19 including generic components, proper event typing, and routing integration (TanStack Router, React Router).
---

# React TypeScript

Type-safe React = compile-time guarantees = confident refactoring.

<when_to_use>

- Building typed React components
- Implementing generic components
- Typing event handlers, forms, refs
- Using React 19 features (Actions, Server Components, use())
- Router integration (TanStack Router, React Router)
- Custom hooks with proper typing

NOT for: non-React TypeScript, vanilla JS React

</when_to_use>

<react_19_changes>

React 19 breaking changes require migration. Key patterns:

**ref as prop** - forwardRef deprecated:

```typescript
// React 19 - ref as regular prop
type ButtonProps = {
  ref?: React.Ref<HTMLButtonElement>;
} & React.ComponentPropsWithoutRef<'button'>;

function Button({ ref, children, ...props }: ButtonProps) {
  return <button ref={ref} {...props}>{children}</button>;
}
```

**useActionState** - replaces useFormState:

```typescript
import { useActionState } from 'react';

type FormState = { errors?: string[]; success?: boolean };

function Form() {
  const [state, formAction, isPending] = useActionState(submitAction, {});
  return <form action={formAction}>...</form>;
}
```

**use()** - unwraps promises/context:

```typescript
function UserProfile({ userPromise }: { userPromise: Promise<User> }) {
  const user = use(userPromise); // Suspends until resolved
  return <div>{user.name}</div>;
}
```

See [react-19-patterns.md](references/react-19-patterns.md) for useOptimistic, useTransition, migration checklist.

</react_19_changes>

<component_patterns>

**Props** - extend native elements:

```typescript
type ButtonProps = {
  variant: 'primary' | 'secondary';
} & React.ComponentPropsWithoutRef<'button'>;

function Button({ variant, children, ...props }: ButtonProps) {
  return <button className={variant} {...props}>{children}</button>;
}
```

**Children typing**:

```typescript
type Props = {
  children: React.ReactNode;          // Anything renderable
  icon: React.ReactElement;           // Single element
  render: (data: T) => React.ReactNode;  // Render prop
};
```

**Discriminated unions** for variant props:

```typescript
type ButtonProps =
  | { variant: 'link'; href: string }
  | { variant: 'button'; onClick: () => void };

function Button(props: ButtonProps) {
  if (props.variant === 'link') {
    return <a href={props.href}>Link</a>;
  }
  return <button onClick={props.onClick}>Button</button>;
}
```

</component_patterns>

<event_handlers>

Use specific event types for accurate target typing:

```typescript
// Mouse
function handleClick(e: React.MouseEvent<HTMLButtonElement>) {
  e.currentTarget.disabled = true;
}

// Form
function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
  e.preventDefault();
  const formData = new FormData(e.currentTarget);
}

// Input
function handleChange(e: React.ChangeEvent<HTMLInputElement>) {
  console.log(e.target.value);
}

// Keyboard
function handleKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {
  if (e.key === 'Enter') e.currentTarget.blur();
}
```

See [event-handlers.md](references/event-handlers.md) for focus, drag, clipboard, touch, wheel events.

</event_handlers>

<hooks_typing>

**useState** - explicit for unions/null:

```typescript
const [user, setUser] = useState<User | null>(null);
const [status, setStatus] = useState<'idle' | 'loading'>('idle');
```

**useRef** - null for DOM, value for mutable:

```typescript
const inputRef = useRef<HTMLInputElement>(null);  // DOM - use ?.
const countRef = useRef<number>(0);               // Mutable - direct access
```

**useReducer** - discriminated unions for actions:

```typescript
type Action =
  | { type: 'increment' }
  | { type: 'set'; payload: number };

function reducer(state: State, action: Action): State {
  switch (action.type) {
    case 'set': return { ...state, count: action.payload };
    default: return state;
  }
}
```

**Custom hooks** - tuple returns with as const:

```typescript
function useToggle(initial = false) {
  const [value, setValue] = useState(initial);
  const toggle = () => setValue(v => !v);
  return [value, toggle] as const;
}
```

**useContext** - null guard pattern:

```typescript
const UserContext = createContext<User | null>(null);

function useUser() {
  const user = useContext(UserContext);
  if (!user) throw new Error('useUser outside UserProvider');
  return user;
}
```

See [hooks.md](references/hooks.md) for useCallback, useMemo, useImperativeHandle, useSyncExternalStore.

</hooks_typing>

<generic_components>

Generic components infer types from props - no manual annotations at call site.

**Pattern** - keyof T for column keys, render props for custom rendering:

```typescript
type Column<T> = {
  key: keyof T;
  header: string;
  render?: (value: T[keyof T], item: T) => React.ReactNode;
};

type TableProps<T> = {
  data: T[];
  columns: Column<T>[];
  keyExtractor: (item: T) => string | number;
};

function Table<T>({ data, columns, keyExtractor }: TableProps<T>) {
  return (
    <table>
      <thead>
        <tr>{columns.map(col => <th key={String(col.key)}>{col.header}</th>)}</tr>
      </thead>
      <tbody>
        {data.map(item => (
          <tr key={keyExtractor(item)}>
            {columns.map(col => (
              <td key={String(col.key)}>
                {col.render ? col.render(item[col.key], item) : String(item[col.key])}
              </td>
            ))}
          </tr>
        ))}
      </tbody>
    </table>
  );
}
```

**Constrained generics** for required properties:

```typescript
type HasId = { id: string | number };

function List<T extends HasId>({ items }: { items: T[] }) {
  return <ul>{items.map(item => <li key={item.id}>...</li>)}</ul>;
}
```

See [generic-components.md](examples/generic-components.md) for Select, List, Modal, FormField patterns.

</generic_components>

<server_components>

React 19 Server Components run on server, can be async.

**Async data fetching**:

```typescript
export default async function UserPage({ params }: { params: { id: string } }) {
  const user = await fetchUser(params.id);
  return <div>{user.name}</div>;
}
```

**Server Actions** - 'use server' for mutations:

```typescript
'use server';

export async function updateUser(userId: string, formData: FormData) {
  await db.user.update({ where: { id: userId }, data: { ... } });
  revalidatePath(`/users/${userId}`);
}
```

**Client + Server Action**:

```typescript
'use client';

import { useActionState } from 'react';
import { updateUser } from '@/actions/user';

function UserForm({ userId }: { userId: string }) {
  const [state, formAction, isPending] = useActionState(
    (prev, formData) => updateUser(userId, formData), {}
  );
  return <form action={formAction}>...</form>;
}
```

**use() for promise handoff**:

```typescript
// Server: pass promise without await
async function Page() {
  const userPromise = fetchUser('123');
  return <UserProfile userPromise={userPromise} />;
}

// Client: unwrap with use()
'use client';
function UserProfile({ userPromise }: { userPromise: Promise<User> }) {
  const user = use(userPromise);
  return <div>{user.name}</div>;
}
```

See [server-components.md](examples/server-components.md) for parallel fetching, streaming, error boundaries.

</server_components>

<routing>

Both TanStack Router and React Router v7 provide type-safe routing solutions.

**TanStack Router** - Compile-time type safety with Zod validation:

```typescript
import { createRoute } from '@tanstack/react-router';
import { z } from 'zod';

const userRoute = createRoute({
  path: '/users/$userId',
  component: UserPage,
  loader: async ({ params }) => ({ user: await fetchUser(params.userId) }),
  validateSearch: z.object({
    tab: z.enum(['profile', 'settings']).optional(),
    page: z.number().int().positive().default(1),
  }),
});

function UserPage() {
  const { user } = useLoaderData({ from: userRoute.id });
  const { tab, page } = useSearch({ from: userRoute.id });
  const { userId } = useParams({ from: userRoute.id });
}
```

**React Router v7** - Automatic type generation with Framework Mode:

```typescript
import type { Route } from "./+types/user";

export async function loader({ params }: Route.LoaderArgs) {
  return { user: await fetchUser(params.userId) };
}

export default function UserPage({ loaderData }: Route.ComponentProps) {
  const { user } = loaderData; // Typed from loader
  return <h1>{user.name}</h1>;
}
```

See [tanstack-router.md](references/tanstack-router.md) for TanStack patterns and [react-router.md](references/react-router.md) for React Router patterns.

</routing>

<rules>

ALWAYS:
- Specific event types (MouseEvent, ChangeEvent, etc)
- Explicit useState for unions/null
- ComponentPropsWithoutRef for native element extension
- Discriminated unions for variant props
- as const for tuple returns
- ref as prop in React 19 (no forwardRef)
- useActionState for form actions
- Type-safe routing patterns (see routing section)

NEVER:
- any for event handlers
- JSX.Element for children (use ReactNode)
- forwardRef in React 19+
- useFormState (deprecated)
- Forget null handling for DOM refs
- Mix Server/Client components in same file
- Await promises when passing to use()

</rules>

<references>

- [hooks.md](references/hooks.md) - useState, useRef, useReducer, useContext, custom hooks
- [event-handlers.md](references/event-handlers.md) - all event types, generic handlers
- [react-19-patterns.md](references/react-19-patterns.md) - useActionState, use(), useOptimistic, migration
- [generic-components.md](examples/generic-components.md) - Table, Select, List, Modal patterns
- [server-components.md](examples/server-components.md) - async components, Server Actions, streaming
- [tanstack-router.md](references/tanstack-router.md) - TanStack Router typed routes, search params, navigation
- [react-router.md](references/react-router.md) - React Router v7 loaders, actions, type generation, forms

</references>

© softaworks · MIT · softaworks/agent-toolkit

Смотрите также

Спонсоры проекта

Компании, которые помогают держать аналитику открытой