Skip to main content

react-dev

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 TanStack Router integration.

Quellinformationen

Repository
outfitter-dev/agents
Letzte Quellaktivität
27. Januar 2026 um 15:45
Erkannte Sprache von SKILL.md
Englisch
Sterne
28
Forks
1

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
7 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
react-dev
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 TanStack Router integration.
metadata
{"version":"1.0.0"}
# 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()) - TanStack Router integration - 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> <tanstack_integration> TanStack Router = type-safe routes, params, search params, loader data. **Route 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), }), }); ``` **Typed hooks**: ```typescript function UserPage() { const { user } = useLoaderData({ from: userRoute.id }); const { tab, page } = useSearch({ from: userRoute.id }); const { userId } = useParams({ from: userRoute.id }); } ``` **Type-safe navigation**: ```typescript navigate({ to: '/users/$userId', params: { userId }, search: { tab: 'profile' }, // Type-checked }); ``` See [tanstack-router.md](references/tanstack-router.md) for nested routes, beforeLoad, error handling, React Query integration. </tanstack_integration> <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 - Zod validation for TanStack Router search params 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) - typed routes, search params, navigation </references>
Auf GitHub ansehen