拥抱React+TS___2026-02-20
1. 环境准备 & 核心工具库 (Setup)
📦 必装依赖
# 1. 状态管理 & 数据请求 (替代 useEffect fetch)
npm install @tanstack/react-query
# 2. 类型生成 (开发依赖)
npm install -D openapi-typescript
# 3. 样式管理 (Tailwind 体系)
npm install class-variance-authority clsx tailwind-merge
# 4. 工具库
npm install lodash @types/lodash
# 5. 代码定位神器: https://inspector.fe-dev.cn/guide/start.html
npm install code-inspector-plugin -D
🛠 VS Code 效率插件
- Tailwind CSS IntelliSense: 智能提示,必装。
- Pretty TypeScript Errors: 让类型报错说人话。
- Inline Fold: (可选) 折叠 Tailwind 长字符串,眼不见心不烦。
- Cursor 编辑器: 推荐作为主力 IDE,替代手动维护上下文。
🔧 全局类型工具
在 src/types/global.d.ts 中加入,用于鼠标悬停时展开复杂类型:
export type Prettify<T> = {
[K in keyof T]: T[K];
} & {};
2. 核心工作流 (The Golden Data Flow)
这是从后端到前端的单向数据流水线,核心思想是 “防腐层 (ACL)” 和 “模型驱动”。
Step 1: 后端定义 (FastAPI)
- 后端使用 Pydantic 定义
Response Model。 - FastAPI 自动生成
/openapi.json。
Step 2: 类型同步 (DTO Generation)
不要手写后端接口类型,在 package.json 配置脚本:
"scripts": {
"gen-types": "npx openapi-typescript http://localhost:8000/openapi.json --output src/types/api.ts"
}
- 操作:后端接口一变 -> 运行
npm run gen-types-> 前端报错 -> 修正。
Step 3: 数据清洗 (Model Class Pattern)
不要在组件中直接使用 DTO。 创建 Class 来清洗数据。
- 位置:
src/models/User.ts - 作用:类型定义 + 数据转换 (int()函数) + 默认值处理。
import { components } from '@/types/api';
export class UserModel {
id: string;
fullName: string;
avatar: string;
// ✅ 构造函数即“转换器”
constructor(data: components['schemas']['UserDTO']) {
this.id = String(data.u_id);
this.fullName = `${data.first_name} ${data.last_name}`;
this.avatar = data.img_url || '/default.png';
}
}
Step 4: 原子化 Hooks (Atomic Hooks)
不要写上帝 Hook,拆分为原子 Hook,并利用 React Query 缓存。
- 位置:
src/hooks/useUser.ts
export const useUser = (id: string) => {
return useQuery({
queryKey: ['user', id],
queryFn: async () => {
const res = await fetch(`/api/users/${id}`).then(r => r.json());
return new UserModel(res); // ✨ 实例化
}
});
};
3. React Hooks 使用准则
| Hook | 核心原则 (Do’s & Don’ts) | 开销 |
|---|---|---|
| useState | 只存最原始的数据。能算出来的绝不存 State。 | ⭐ |
| useEffect | 同步专用(DOM、Title)。❌ 严禁用于数据流转换(setA -> Effect -> setB)。 | ⭐⭐ |
| Computed | 直接写在函数体内(return 之前)。最高效,每次渲染自动更新。 | ⭐ |
| useRef | 存数据但不触发渲染。用于 Timer、DOM 引用。 | 🆓 (免费) |
| useCallback | 只用于:保持引用稳定(传给 Memo 子组件、作为 Effect 依赖)。 | ⭐⭐ (有成本) |
| useMemo | 只用于:昂贵计算(大数组遍历)。简单的拼接不要用。 | ⭐⭐⭐ |
4. 样式工作流 (Styling with Tailwind)
选择 Tailwind CSS,并使用工程化手段解决“长字符串”和“主题”问题。
🎨 核心库:CVA (Class Variance Authority)
替代 LESS Mixin,像写配置一样写样式。
// components/ui/button.tsx
import { cva } from 'class-variance-authority';
import { cn } from '@/lib/utils'; // 用于合并 class
const buttonVariants = cva(
"inline-flex items-center justify-center rounded-md transition-colors", // 基础样式
{
variants: {
variant: { // 变体
default: "bg-primary text-primary-foreground hover:bg-primary/90",
outline: "border border-input hover:bg-accent",
},
size: { // 尺寸
default: "h-10 px-4 py-2",
sm: "h-9 rounded-md px-3",
},
},
defaultVariants: { variant: "default", size: "default" },
}
);
// 使用:<button className={cn(buttonVariants({ variant: 'outline' }))} />
🌗 主题系统 (Theming)
不要用 LESS 变量,使用 CSS Variables + Tailwind Config。
-
globals.css: 定义 CSS 变量(支持运行时切换深色模式)。
:root { --primary: 222.2 47.4% 11.2%; } .dark { --primary: 210 40% 98%; } -
tailwind.config.js: 绑定变量。
theme: { extend: { colors: { primary: "hsl(var(--primary))" } } } -
开发: 使用语义化 Class。
<div class="bg-primary text-primary-foreground">...</div>
🚀 快速起步推荐
直接使用 shadcn/ui 初始化项目。它会自动配置好上述的 cva、cn 工具函数以及主题变量系统。
npx shadcn-ui@latest init
5. 组件架构原则
就近原则 (Co-location)
- Props 定义:直接写在组件文件里 (
interface Props {})。 - 页面状态:直接写在
page.tsx里。 - 全局类型:只有跨多个文件使用的 Model 才放
src/types或src/models。
ID 驱动开发 (ID-Driven)
-
Smart Component (业务组件):只接收
id(e.g.,<UserAvatar userId="123" />)。- 内部自行调用
useUser(id)。 - 利用 React Query 自动去重和缓存,避免 Prop Drilling。
- 内部自行调用
-
Dumb Component (UI 组件):只接收数据 (e.g.,
<Avatar src="..." />)。- 纯展示,不包含业务逻辑。