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 routing integration (TanStack Router, React Router).
跳到安装 Skills Marketplace 发现并探索由社区构建的 Agent Skills
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/jvegaf/harmony --skill react-dev命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
下载 Zip 下载中... 同仓库更多 Skills Master effective code review practices to provide constructive feedback, catch bugs early, and foster knowledge sharing while maintaining team morale. Use when reviewing pull requests, establishing review standards, or mentoring developers.
Type-safe SQL ORM for TypeScript with zero runtime overhead
Provides comprehensive guidance for Electron framework including main process, renderer process, IPC communication, window management, and desktop app development. Use when the user asks about Electron, needs to create desktop applications, implement Electron features, or build cross-platform desktop apps.
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:
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:
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:
function UserProfile ({ userPromise }: { userPromise: Promise <User> } ) {
const user = use (userPromise);
return <div > {user.name}</div > ;
}
Props - extend native elements:
type ButtonProps = {
variant : 'primary' | 'secondary' ;
} & React .ComponentPropsWithoutRef <'button' >;
function Button ({ variant, children, ...props }: ButtonProps ) {
return <button className ={variant} {...props }> {children}</button > ;
}
type Props = {
children : React .ReactNode ;
icon : React .ReactElement ;
render : (data : T ) => React .ReactNode ;
};
Discriminated unions for variant props:
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 > ;
}
Use specific event types for accurate target typing:
function handleClick (e : React .MouseEvent <HTMLButtonElement > ) {
e.currentTarget .disabled = true ;
}
function handleSubmit (e : React .FormEvent <HTMLFormElement > ) {
e.preventDefault ();
const formData = new FormData (e.currentTarget );
}
function handleChange (e : React .ChangeEvent <HTMLInputElement > ) {
console .log (e.target .value );
}
function handleKeyDown (e : React .KeyboardEvent <HTMLInputElement > ) {
if (e.key === 'Enter' ) e.currentTarget .blur ();
}
useState - explicit for unions/null:
const [user, setUser] = useState<User | null >(null );
const [status, setStatus] = useState<'idle' | 'loading' >('idle' );
useRef - null for DOM, value for mutable:
const inputRef = useRef<HTMLInputElement >(null );
const countRef = useRef<number >(0 );
useReducer - discriminated unions for actions:
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:
function useToggle (initial = false ) {
const [value, setValue] = useState (initial);
const toggle = ( ) => setValue (v => !v);
return [value, toggle] as const ;
}
useContext - null guard pattern:
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 for useCallback, useMemo, useImperativeHandle, useSyncExternalStore.
Generic components infer types from props - no manual annotations at call site.
Pattern - keyof T for column keys, render props for custom rendering:
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:
type HasId = { id : string | number };
function List <T extends HasId >({ items }: { items : T[] }) {
return <ul > {items.map(item => <li key ={item.id} > ...</li > )}</ul > ;
}
React 19 Server Components run on server, can be async.
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:
'use server' ;
export async function updateUser (userId : string , formData : FormData ) {
await db.user .update ({ where : { id : userId }, data : { ... } });
revalidatePath (`/users/${userId} ` );
}
'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 :
async function Page ( ) {
const userPromise = fetchUser ('123' );
return <UserProfile userPromise ={userPromise} /> ;
}
'use client' ;
function UserProfile ({ userPromise }: { userPromise: Promise <User> } ) {
const user = use (userPromise);
return <div > {user.name}</div > ;
}
Both TanStack Router and React Router v7 provide type-safe routing solutions.
TanStack Router - Compile-time type safety with Zod validation:
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:
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;
return <h1 > {user.name}</h1 > ;
}
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)
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()
hooks.md - useState, useRef, useReducer, useContext, custom hooks
event-handlers.md - all event types, generic handlers
react-19-patterns.md - useActionState, use(), useOptimistic, migration
generic-components.md - Table, Select, List, Modal patterns
server-components.md - async components, Server Actions, streaming
tanstack-router.md - TanStack Router typed routes, search params, navigation
react-router.md - React Router v7 loaders, actions, type generation, forms