[ PROMPT_NODE_25265 ]
React Dev
[ SKILL_DOCUMENTATION ]
# React TypeScript Development Skill
## Purpose
The `react-dev` skill provides comprehensive TypeScript patterns and best practices for building type-safe React applications. It serves as a complete reference for modern React development with TypeScript, covering React 18-19 features, including Server Components, type-safe routing, and proper event handling.
This skill exists to eliminate TypeScript guesswork in React development by providing compile-time guarantees, confident refactoring, and production-ready patterns that catch bugs before runtime.
## When to Use
Activate this skill when working on:
- **Building typed React components** - Creating new components with proper TypeScript types
- **Implementing generic components** - Tables, lists, modals, form fields that work with any data type
- **Typing event handlers and forms** - Mouse events, form submissions, input changes, keyboard events
- **Using React 19 features** - Actions, Server Components, `use()` hook, `useActionState`
- **Router integration** - TanStack Router or React Router v7 with type safety
- **Custom hooks with proper typing** - Creating reusable hooks with correct return types
- **Migrating to React 19** - Understanding breaking changes and new patterns
**Trigger phrases:**
- "Build a typed React component"
- "Type this event handler"
- "Create a generic Table/List/Modal"
- "Use React 19 Server Components"
- "Type-safe routing with TanStack/React Router"
- "How do I type this hook?"
- "React TypeScript best practices"
**Not for:**
- Non-React TypeScript projects
- Vanilla JavaScript React (without TypeScript)
- React Native-specific patterns
## How It Works
The skill provides progressive disclosure of React TypeScript knowledge:
1. **Core patterns loaded immediately** - Component props, event handlers, hooks typing
2. **Advanced patterns referenced on-demand** - Generic components, Server Components, routing
3. **Reference files for deep dives** - Detailed examples and edge cases only loaded when needed
4. **React 19 migration guidance** - Breaking changes and new APIs clearly marked
The skill is structured around:
- **Quick reference sections** - Common patterns you can copy immediately
- **Detailed reference files** - In-depth examples and explanations
- **Rules and anti-patterns** - What to always do and what to never do
- **Version-specific guidance** - React 18 vs React 19 differences highlighted
## Key Features
### 1. React 19 Breaking Changes
Covers all major breaking changes in React 19:
- **ref as prop** - No more `forwardRef`, refs are regular props now
- **useActionState** - Replaces deprecated `useFormState`
- **use() hook** - Unwraps promises and context in components
- **Migration patterns** - Step-by-step guides for updating existing code
### 2. Component Patterns
Type-safe patterns for common component scenarios:
- **Props typing** - Extending native HTML elements with `ComponentPropsWithoutRef`
- **Children typing** - `ReactNode`, `ReactElement`, render props
- **Discriminated unions** - Type-safe variant props (e.g., button vs link)
- **Generic components** - Reusable components that infer types from data
### 3. Event Handler Typing
Specific event types for accurate TypeScript inference:
- Mouse events (`MouseEvent`)
- Form events (`FormEvent`)
- Input changes (`ChangeEvent`)
- Keyboard events (`KeyboardEvent`)
- Focus, drag, clipboard, touch, wheel events (in reference docs)
### 4. Hooks Typing
Proper TypeScript patterns for all React hooks:
- `useState` - Explicit types for unions and nullable values
- `useRef` - DOM refs (null) vs mutable refs (direct access)
- `useReducer` - Discriminated union actions
- `useContext` - Null guard patterns
- Custom hooks - Tuple returns with `as const`
### 5. Server Components (React 19)
Modern patterns for Server Components and Server Actions:
- Async components with direct data fetching
- Server Actions with `'use server'` directive
- Client components consuming Server Actions
- Promise handoff with `use()` hook
- Parallel fetching and streaming
### 6. Type-Safe Routing
Comprehensive routing patterns for both major routers:
- **TanStack Router** - Compile-time type safety with Zod validation
- **React Router v7** - Auto-generated types with Framework Mode
- Type-safe params, search params, loaders, actions
### 7. Generic Components
Reusable components that work with any data type:
- Tables with type-safe columns
- Lists with constrained generics
- Modals, selects, form fields
- Render props and keyof patterns
## Prerequisites
- **React 18 or 19** - Patterns are optimized for modern React
- **TypeScript 5.0+** - Uses latest TypeScript features
- **Router (optional)** - TanStack Router or React Router v7 for routing patterns
- **Zod (optional)** - For TanStack Router search param validation
## Usage Examples
### Example 1: Type-Safe Button Component
```typescript
type ButtonProps = {
variant: 'primary' | 'secondary';
} & React.ComponentPropsWithoutRef;
function Button({ variant, children, ...props }: ButtonProps) {
return (
);
}
// Usage
```
### Example 2: Generic Table Component
```typescript
type Column = {
key: keyof T;
header: string;
render?: (value: T[keyof T], item: T) => React.ReactNode;
};
type TableProps = {
data: T[];
columns: Column[];
keyExtractor: (item: T) => string | number;
};
function Table({ data, columns, keyExtractor }: TableProps) {
return (
);
}
// Usage - types are inferred!
type User = { id: number; name: string; email: string };
const users: User[] = [...];
user.id}
/>
```
### Example 3: React 19 Server Action with Form
```typescript
// actions/user.ts
'use server';
export async function updateUser(userId: string, formData: FormData) {
const name = formData.get('name') as string;
await db.user.update({
where: { id: userId },
data: { name }
});
revalidatePath(`/users/${userId}`);
return { success: true };
}
// UserForm.tsx
'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 (
{state.success &&
| {col.header} | )}
|---|
| {col.render ? col.render(item[col.key], item) : String(item[col.key])} | ))}