by softaworks
适用于 Claude、Codex 和 Claude Code 的 AI 技能
1. 打开 Claude 聊天界面
2. 点击下方 "📋 复制" 按钮
3. 粘贴到 Claude 聊天框中并发送
4. 输入 "使用 react-dev 技能" 开始使用
=== react-dev 技能 === 作者: softaworks 描述: 适用于 Claude、Codex 和 Claude Code 的 AI 技能 使用方法: 1. 调用技能: "使用 react-dev 技能" 2. 提供相关信息: 根据技能要求提供必要参数 3. 查看结果: 技能会返回处理结果 示例: "使用 react-dev 技能,帮我分析一下这段代码"
这种方法适用于所有 Claude 用户,不需要安装额外工具。
productivity
medium
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.
Activate this skill when working on:
use() hook, useActionStateTrigger phrases:
Not for:
The skill provides progressive disclosure of React TypeScript knowledge:
The skill is structured around:
Covers all major breaking changes in React 19:
forwardRef, refs are regular props nowuseFormStateType-safe patterns for common component scenarios:
ComponentPropsWithoutRefReactNode, ReactElement, render propsSpecific event types for accurate TypeScript inference:
MouseEvent<HTMLButtonElement>)FormEvent<HTMLFormElement>)ChangeEvent<HTMLInputElement>)KeyboardEvent<HTMLInputElement>)Proper TypeScript patterns for all React hooks:
useState - Explicit types for unions and nullable valuesuseRef - DOM refs (null) vs mutable refs (direct access)useReducer - Discriminated union actionsuseContext - Null guard patternsas constModern patterns for Server Components and Server Actions:
'use server' directiveuse() hookComprehensive routing patterns for both major routers:
Reusable components that work with any data type:
type ButtonProps = {
variant: 'primary' | 'secondary';
} & React.ComponentPropsWithoutRef<'button'>;
function Button({ variant, children, ...props }: ButtonProps) {
return (
<button
className={variant}
{...props}
>
{children}
</button>
);
}
// Usage
<Button variant="primary" onClick={(e) => console.log(e.currentTarget.disabled)}>
Click me
</Button>
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>
);
}
// Usage - types are inferred!
type User = { id: number; name: string; email: string };
const users: User[] = [...];
<Table
data={users}
columns={[
{ key: 'name', header: 'Name' },
{ key: 'email', header: 'Email' }
]}
keyExtractor={user => user.id}
/>
// 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 (
<form action={formAction}>
<input name="name" />
<button disabled={isPending}>
{isPending ? 'Saving...' : 'Save'}
</button>
{state.success && <p>Saved!</p>}
</form>
);
}
function Form() {
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const formData = new FormData(e.currentTarget);
console.log(Object.fromEntries(formData));
};
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
console.log(e.target.value); // Typed correctly!
};
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter') {
e.currentTarget.blur(); // currentTarget is typed as HTMLInputElement
}
};
return (
<form onSubmit={handleSubmit}>
<input
onChange={handleChange}
onKeyDown={handleKeyDown}
/>
</form>
);
}
function useToggle(initial = false) {
const [value, setValue] = useState(initial);
const toggle = () => setValue(v => !v);
return [value, toggle] as const; // Tuple type preserved!
}
// Usage
const [isOpen, toggleOpen] = useToggle(false);
// isOpen is boolean, toggleOpen is () => void
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() {
// All fully typed from the route definition!
const { user } = useLoaderData({ from: userRoute.id });
const { tab, page } = useSearch({ from: userRoute.id });
const { userId } = useParams({ from: userRoute.id });
return <div>{user.name} - {tab} - Page {page}</div>;
}
The skill provides:
✅ Use specific event types - MouseEvent<HTMLButtonElement> not React.MouseEvent
✅ Explicit useState for unions/null - useState<User | null>(null)
✅ Extend native elements - ComponentPropsWithoutRef<'button'>
✅ Discriminated unions for variants - Type-safe props based on variant
✅ as const for tuple returns - Preserve tuple types in custom hooks
✅ ref as prop in React 19 - No forwardRef needed
✅ useActionState for forms - Not deprecated useFormState
✅ Type-safe routing patterns - Use provided router patterns
❌ Use any for event handlers - Defeats TypeScript's purpose
❌ Use JSX.Element for children - Use ReactNode instead
❌ Use forwardRef in React 19+ - It's deprecated
❌ Use useFormState - Deprecated in React 19
❌ Forget null handling for DOM refs - Always use ref?.current
❌ Mix Server/Client in same file - Will cause hydration errors
❌ Await promises before use() - Defeats streaming/Suspense
The skill includes detailed reference files:
useState, useRef, useReducer, useContext, custom hooksuseActionState, use(), useOptimistic, migrationThese files are loaded on-demand to keep context efficient. The skill will reference them when deeper knowledge is needed.
This skill follows progressive disclosure principles:
This keeps the skill's context footprint minimal while providing comprehensive coverage when needed.
use(), useActionStatecreateRouteVersion: 1.0.0 Last Updated: 2026-01-20 Maintained by: Softaworks Agent Skills
View Count
0
Download Count
0
Favorite Count
0
Quality Score
56