一、核心原则
- 单向数据流优先
保持数据从父组件流向子组件,避免反向修改 props;React 19 的 Actions 特性进一步强化了这一原则,通过useActionState统一处理表单/交互的状态更新,而非直接修改组件内部状态。 - 组件职责单一
一个组件只负责一个核心功能(如「表单提交按钮」而非「包含表单+列表+弹窗的全能组件」),React 19 的编译器会对单一职责组件做更优的编译优化。 - 优先使用声明式代码
避免命令式操作 DOM,React 19 提供的useFormStatus、useOptimistic等 Hooks 都是声明式的,应优先使用而非手动操作 state。 - 拥抱 React 19 的「编译时优化」
不再依赖memo/useMemo/useCallback做过度优化,React 19 编译器会自动识别纯组件、稳定引用,仅在必要时手动使用这些 API。
二、基础代码规范
1. 组件编写规范
-
组件命名 :
- 函数组件使用 PascalCase(大驼峰):
UserProfile而非userProfile/user_profile; - 组件文件命名与组件名一致,如
UserProfile.tsx; - 私有组件(仅当前文件使用)前缀加下划线:
_UserProfileItem。
- 函数组件使用 PascalCase(大驼峰):
-
组件结构 (推荐顺序):
tsx// 1. 导入依赖(React 核心 → 第三方库 → 本地组件/工具 → 样式) import { useState, useActionState } from 'react'; import { Button } from 'antd'; import { fetchUser } from '@/api/user'; import './UserProfile.css'; // 2. 类型定义(TypeScript 必选) interface UserProfileProps { userId: string; defaultName?: string; } // 3. 纯函数/工具函数(组件外部,避免每次渲染重建) const formatUserName = (name: string) => name.trim() || '未知用户'; // 4. 组件定义(优先箭头函数,明确返回类型) const UserProfile: React.FC<UserProfileProps> = ({ userId, defaultName }) => { // 5. Hooks 调用(置顶,遵循 Hooks 规则) const [userName, setUserName] = useState(defaultName); // 6. 事件/业务逻辑(使用 React 19 Actions 处理异步更新) const updateUser = async (formData: FormData) => { const newName = formData.get('name') as string; await fetchUser(userId, { name: newName }); setUserName(newName); }; // 7. 渲染逻辑 return ( <div className="user-profile"> <p>用户名:{formatUserName(userName)}</p> <form action={updateUser}> <input name="name" defaultValue={userName} /> <button type="submit">修改</button> </form> </div> ); }; // 8. 导出组件(默认导出为主) export default UserProfile;
2. Hooks 使用规范
- 必须遵循 Hooks 规则:仅在组件/自定义 Hooks 顶层调用,不可在循环/条件/嵌套函数中调用;
- React 19 新 Hooks 使用规范 :
-
useActionState:专用于处理表单/交互的异步状态更新,替代手动useState + async/await;tsxconst [state, formAction, isPending] = useActionState( async (prevState, formData) => { // 异步逻辑:请求接口、更新状态 await saveData(formData); return { ...prevState, success: true }; }, { success: false } // 初始状态 ); -
useOptimistic:仅用于「乐观更新」场景(如点赞、提交表单),避免滥用导致状态不一致; -
useFormStatus:用于表单提交状态展示(如禁用按钮、加载动画),而非手动维护loading状态;
-
- 自定义 Hooks 命名 :必须以
use开头(如useUserInfo),返回值优先用对象(便于解构,兼容后续扩展)。
3. TypeScript 规范
-
所有组件/Props 必须定义类型,禁止使用
any; -
优先使用
interface定义 Props,type定义联合类型/复杂类型; -
事件处理函数明确类型:
tsx// 正确 const handleClick: React.MouseEventHandler<HTMLButtonElement> = (e) => { e.preventDefault(); // 逻辑 }; // 错误:未指定事件类型 const handleClick = (e) => {};
三、React 19 新特性专项规范
1. Actions 规范(核心新特性)
- 表单优先使用
action属性绑定 Actions,替代onSubmit手动处理; - Actions 函数参数优先使用
FormData(而非解构e.target),符合 Web 标准; - 避免在 Actions 中直接修改 DOM,通过返回值更新状态;
- 使用
useFormStatus获取提交状态,而非手动维护loading变量。
2. 编译器优化规范
-
不再过度使用
React.memo/useMemo/useCallback:React 19 编译器会自动优化纯组件、稳定引用; -
仅在「非纯组件」「频繁渲染且计算成本高」的场景手动使用
memo/useMemo; -
避免在组件内定义「不稳定引用」(如内联对象/函数),编译器无法优化此类场景:
tsx// 不推荐:每次渲染重建对象 return <Child style={{ color: 'red' }} />; // 推荐:提取为常量 const childStyle = { color: 'red' }; return <Child style={childStyle} />;
3. 服务器组件(RSC)规范
- 区分「服务器组件」(.server.tsx)和「客户端组件」(.client.tsx),客户端组件需显式标记
'use client'; - 服务器组件中禁止使用 Hooks、浏览器 API(如
window/document); - 客户端组件仅负责交互逻辑,数据请求优先放在服务器组件中。
四、性能与工程化规范
1. 性能优化
- 列表渲染必须加
key,且key需稳定(避免使用索引); - 避免不必要的重渲染:React 19 编译器已优化,但仍需避免「状态提升过度」「传递不稳定 props」;
- 大列表使用虚拟滚动(如
react-window),而非直接渲染全部数据。
2. 工程化
-
目录结构 (推荐):
src/ ├── components/ # 通用组件(按功能分目录) │ ├── Button/ # 组件目录(单组件单目录) │ │ ├── index.tsx # 组件入口 │ │ ├── Button.tsx │ │ └── Button.css ├── hooks/ # 自定义 Hooks ├── api/ # 接口请求 ├── pages/ # 页面组件(对应路由) ├── types/ # 全局类型定义 └── utils/ # 工具函数 -
样式规范:优先使用 CSS Modules/Tailwind CSS,避免全局样式污染;
-
代码检查 :集成 ESLint + Prettier,使用
eslint-plugin-react-hooks检查 Hooks 规则,eslint-plugin-react开启 React 19 规则; -
提交规范 :使用 Conventional Commits(如
feat: 新增用户信息组件fix: 修复表单提交状态错误)。