更新技术栈文档,新增TanStack Query和Sentry组件,优化项目结构说明,添加关于兼容性和工程化的详细信息。
This commit is contained in:
767
Touchkebao/React代码编写规范.md
Normal file
767
Touchkebao/React代码编写规范.md
Normal file
@@ -0,0 +1,767 @@
|
||||
# React 代码编写规范大全
|
||||
|
||||
> 参考来源:[React 代码编写规范大全:从基础到架构,打造可维护的企业级应用](https://blog.csdn.net/qq_16242613/article/details/150996674)
|
||||
|
||||
编写 React 代码不仅仅是让功能跑起来,更重要的是保证代码的可读性、可维护性和团队协作效率。一套良好的编码规范是达成这些目标的基石。
|
||||
|
||||
本文将从**基础规范**、**组件设计**、**状态管理**、**样式处理**、**性能优化**和**项目架构**六个层次,由浅入深地详解 React 的代码编写规范。
|
||||
|
||||
---
|
||||
|
||||
## 📋 目录
|
||||
|
||||
- [一、核心六层规范架构](#一核心六层规范架构)
|
||||
- [二、L1 - 基础与核心规范](#二l1---基础与核心规范)
|
||||
- [三、L2 - 组件设计模式](#三l2---组件设计模式)
|
||||
- [四、L3 - 状态管理规范](#四l3---状态管理规范)
|
||||
- [五、L4 - 样式与CSS策略](#五l4---样式与css策略)
|
||||
- [六、L5 - 性能优化指南](#六l5---性能优化指南)
|
||||
- [七、L6 - 项目结构与架构](#七l6---项目结构与架构)
|
||||
|
||||
---
|
||||
|
||||
## 一、核心六层规范架构
|
||||
|
||||
React 代码规范的六个核心层次,构成了一个完整、健壮的应用开发体系:
|
||||
|
||||
```
|
||||
React 代码规范六层体系
|
||||
├── L1: 基础与核心规范 (命名、文件组织、JSX、PropTypes)
|
||||
│ └── 目标: 代码一致性与可读性
|
||||
├── L2: 组件设计模式 (组件拆分、组合、解耦)
|
||||
│ └── 目标: 可复用与可维护性
|
||||
├── L3: 状态管理规范 (State原则、Reducer、Context、Redux)
|
||||
│ └── 目标: 数据流清晰与可预测
|
||||
├── L4: 样式与CSS策略 (CSS Modules、Styled-Components、方案选型)
|
||||
│ └── 目标: 样式可控与避免冲突
|
||||
├── L5: 性能优化指南 (Memo、Callback、懒加载、列表优化)
|
||||
│ └── 目标: 应用流畅与用户体验
|
||||
└── L6: 项目结构与架构 (目录组织、路由、配置、静态资源)
|
||||
└── 目标: 项目可扩展与易于协作
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 二、L1 - 基础与核心规范
|
||||
|
||||
这是最基础也是必须遵守的规范,保证了代码的一致性和可读性。
|
||||
|
||||
### 1. 命名规范 (Naming Conventions)
|
||||
|
||||
#### 组件命名
|
||||
|
||||
使用 **PascalCase** (大驼峰命名法),且名称与文件名一致。
|
||||
|
||||
```tsx
|
||||
// ✅ 正确
|
||||
// UserProfile.tsx
|
||||
function UserProfile() { ... }
|
||||
|
||||
// ❌ 错误
|
||||
// userProfile.tsx
|
||||
function user_profile() { ... }
|
||||
function User_Profile() { ... }
|
||||
```
|
||||
|
||||
#### 属性命名
|
||||
|
||||
使用 **camelCase** (小驼峰命名法)。
|
||||
|
||||
```tsx
|
||||
// ✅ 正确
|
||||
<Button onClick={handleClick} userName={userName} />
|
||||
|
||||
// ❌ 错误
|
||||
<Button ONCLICK={handleClick} UserName={userName} />
|
||||
```
|
||||
|
||||
#### 自定义事件处理函数
|
||||
|
||||
以 `handle` 开头,后接事件名或操作名。
|
||||
|
||||
```tsx
|
||||
const handleInputChange = () => { ... };
|
||||
const handleSubmit = () => { ... };
|
||||
const handleDeleteUser = () => { ... };
|
||||
```
|
||||
|
||||
#### 布尔型 Props
|
||||
|
||||
前缀使用 `is`, `has`, `should` 等,使其语义更明确。
|
||||
|
||||
```tsx
|
||||
// ✅ 正确
|
||||
<Button isDisabled={true} hasError={false} shouldShow={true} />
|
||||
|
||||
// ❌ 错误
|
||||
<Button disabled={true} error={false} show={true} />
|
||||
```
|
||||
|
||||
#### 常量命名
|
||||
|
||||
使用 **UPPER_SNAKE_CASE** (全大写下划线分隔)。
|
||||
|
||||
```tsx
|
||||
const MAX_COUNT = 10;
|
||||
const API_BASE_URL = "https://api.example.com";
|
||||
const DEFAULT_TIMEOUT = 5000;
|
||||
```
|
||||
|
||||
### 2. 文件组织 (File Organization)
|
||||
|
||||
#### 文件命名
|
||||
|
||||
- 组件文件:使用 PascalCase,如 `UserProfile.tsx`
|
||||
- 工具函数:使用 camelCase,如 `formatDate.ts`
|
||||
- 常量文件:使用 UPPER_SNAKE_CASE,如 `API_CONSTANTS.ts`
|
||||
- 样式文件:使用 kebab-case 或与组件同名,如 `user-profile.module.scss` 或 `UserProfile.module.scss`
|
||||
|
||||
#### 目录结构
|
||||
|
||||
```
|
||||
src/
|
||||
├── components/ # 通用组件
|
||||
│ ├── Button/
|
||||
│ │ ├── index.tsx
|
||||
│ │ ├── Button.module.scss
|
||||
│ │ └── types.ts
|
||||
│ └── Modal/
|
||||
├── pages/ # 页面组件
|
||||
│ ├── Home/
|
||||
│ └── Profile/
|
||||
├── hooks/ # 自定义 Hooks
|
||||
├── utils/ # 工具函数
|
||||
├── store/ # 状态管理
|
||||
├── api/ # API 接口
|
||||
└── types/ # TypeScript 类型定义
|
||||
```
|
||||
|
||||
### 3. JSX 编写规范
|
||||
|
||||
#### 基本规则
|
||||
|
||||
```tsx
|
||||
// ✅ 正确:自闭合标签
|
||||
<img src={avatar} alt="Avatar" />
|
||||
<input type="text" value={value} />
|
||||
|
||||
// ❌ 错误
|
||||
<img src={avatar} alt="Avatar"></img>
|
||||
<input type="text" value={value}></input>
|
||||
```
|
||||
|
||||
#### 条件渲染
|
||||
|
||||
```tsx
|
||||
// ✅ 推荐:使用逻辑与运算符
|
||||
{
|
||||
isLoading && <LoadingSpinner />;
|
||||
}
|
||||
|
||||
// ✅ 推荐:三元运算符(简单条件)
|
||||
{
|
||||
isLoggedIn ? <UserMenu /> : <LoginButton />;
|
||||
}
|
||||
|
||||
// ✅ 推荐:提前返回(复杂条件)
|
||||
if (!user) return <LoginPrompt />;
|
||||
return <Dashboard />;
|
||||
```
|
||||
|
||||
#### 列表渲染
|
||||
|
||||
```tsx
|
||||
// ✅ 正确:使用 key
|
||||
{
|
||||
users.map(user => <UserItem key={user.id} user={user} />);
|
||||
}
|
||||
|
||||
// ❌ 错误:使用索引作为 key(除非列表是静态的)
|
||||
{
|
||||
users.map((user, index) => <UserItem key={index} user={user} />);
|
||||
}
|
||||
```
|
||||
|
||||
#### 属性展开
|
||||
|
||||
```tsx
|
||||
// ✅ 正确:使用展开运算符
|
||||
const props = { name: "John", age: 30 };
|
||||
<UserProfile {...props} />
|
||||
|
||||
// ❌ 错误:逐个传递
|
||||
<UserProfile name={props.name} age={props.age} />
|
||||
```
|
||||
|
||||
### 4. Props 类型检查
|
||||
|
||||
#### TypeScript 类型定义
|
||||
|
||||
```tsx
|
||||
// ✅ 推荐:使用 TypeScript
|
||||
interface UserProfileProps {
|
||||
name: string;
|
||||
age: number;
|
||||
email?: string;
|
||||
isActive: boolean;
|
||||
onUpdate: (id: number) => void;
|
||||
}
|
||||
|
||||
const UserProfile: React.FC<UserProfileProps> = ({
|
||||
name,
|
||||
age,
|
||||
email,
|
||||
isActive,
|
||||
onUpdate,
|
||||
}) => {
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
#### 默认值
|
||||
|
||||
```tsx
|
||||
// ✅ 使用默认参数
|
||||
const UserProfile: React.FC<UserProfileProps> = ({
|
||||
name,
|
||||
age,
|
||||
email = "",
|
||||
isActive = false,
|
||||
onUpdate,
|
||||
}) => {
|
||||
// ...
|
||||
};
|
||||
|
||||
// 或使用 defaultProps(不推荐,TypeScript 中已废弃)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 三、L2 - 组件设计模式
|
||||
|
||||
### 1. 组件拆分与组合 (Component Splitting & Composition)
|
||||
|
||||
#### 单一职责原则
|
||||
|
||||
每个组件应该只做一件事。
|
||||
|
||||
```tsx
|
||||
// ❌ 错误:组件职责过多
|
||||
const UserDashboard = () => {
|
||||
return (
|
||||
<div>
|
||||
<UserProfile />
|
||||
<UserSettings />
|
||||
<UserMessages />
|
||||
<UserNotifications />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// ✅ 正确:拆分为多个小组件
|
||||
const UserDashboard = () => {
|
||||
return (
|
||||
<div>
|
||||
<UserProfile />
|
||||
<UserSettings />
|
||||
<UserMessages />
|
||||
<UserNotifications />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
#### 组件大小控制
|
||||
|
||||
- 单个组件文件不超过 300 行
|
||||
- 如果超过,考虑拆分为多个子组件
|
||||
- 复杂逻辑提取为自定义 Hook
|
||||
|
||||
```tsx
|
||||
// ✅ 正确:使用自定义 Hook 提取逻辑
|
||||
const useUserData = (userId: number) => {
|
||||
const [user, setUser] = useState(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
fetchUser(userId).then(data => {
|
||||
setUser(data);
|
||||
setLoading(false);
|
||||
});
|
||||
}, [userId]);
|
||||
|
||||
return { user, loading };
|
||||
};
|
||||
|
||||
const UserProfile = ({ userId }: { userId: number }) => {
|
||||
const { user, loading } = useUserData(userId);
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
### 2. 展示组件与容器组件 (Presentational vs Container Components)
|
||||
|
||||
#### 展示组件 (Presentational Components)
|
||||
|
||||
- 只负责 UI 渲染
|
||||
- 通过 props 接收数据和回调
|
||||
- 不依赖业务逻辑
|
||||
|
||||
```tsx
|
||||
// ✅ 展示组件
|
||||
interface ButtonProps {
|
||||
label: string;
|
||||
onClick: () => void;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
const Button: React.FC<ButtonProps> = ({ label, onClick, disabled }) => {
|
||||
return (
|
||||
<button onClick={onClick} disabled={disabled}>
|
||||
{label}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
#### 容器组件 (Container Components)
|
||||
|
||||
- 负责数据获取和状态管理
|
||||
- 包含业务逻辑
|
||||
- 将数据传递给展示组件
|
||||
|
||||
```tsx
|
||||
// ✅ 容器组件
|
||||
const UserListContainer = () => {
|
||||
const [users, setUsers] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
fetchUsers().then(data => {
|
||||
setUsers(data);
|
||||
setLoading(false);
|
||||
});
|
||||
}, []);
|
||||
|
||||
if (loading) return <LoadingSpinner />;
|
||||
|
||||
return <UserList users={users} />;
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、L3 - 状态管理规范
|
||||
|
||||
### 1. State 放置原则
|
||||
|
||||
#### 状态提升 (Lifting State Up)
|
||||
|
||||
将共享状态提升到最近的公共父组件。
|
||||
|
||||
```tsx
|
||||
// ❌ 错误:状态分散
|
||||
const ChildA = () => {
|
||||
const [sharedValue, setSharedValue] = useState("");
|
||||
// ...
|
||||
};
|
||||
|
||||
const ChildB = () => {
|
||||
const [sharedValue, setSharedValue] = useState("");
|
||||
// ...
|
||||
};
|
||||
|
||||
// ✅ 正确:状态提升
|
||||
const Parent = () => {
|
||||
const [sharedValue, setSharedValue] = useState("");
|
||||
return (
|
||||
<>
|
||||
<ChildA value={sharedValue} onChange={setSharedValue} />
|
||||
<ChildB value={sharedValue} onChange={setSharedValue} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
#### 状态位置判断
|
||||
|
||||
- **组件内部状态**:只在该组件内使用
|
||||
- **共享状态**:提升到公共父组件或使用全局状态管理
|
||||
- **服务器状态**:使用 React Query 或 SWR
|
||||
|
||||
### 2. 使用 useReducer 管理复杂状态
|
||||
|
||||
当状态逻辑复杂时,使用 `useReducer` 替代多个 `useState`。
|
||||
|
||||
```tsx
|
||||
// ✅ 使用 useReducer
|
||||
interface State {
|
||||
count: number;
|
||||
step: number;
|
||||
}
|
||||
|
||||
type Action =
|
||||
| { type: "increment" }
|
||||
| { type: "decrement" }
|
||||
| { type: "reset" }
|
||||
| { type: "setStep"; step: number };
|
||||
|
||||
const reducer = (state: State, action: Action): State => {
|
||||
switch (action.type) {
|
||||
case "increment":
|
||||
return { ...state, count: state.count + state.step };
|
||||
case "decrement":
|
||||
return { ...state, count: state.count - state.step };
|
||||
case "reset":
|
||||
return { ...state, count: 0 };
|
||||
case "setStep":
|
||||
return { ...state, step: action.step };
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
const Counter = () => {
|
||||
const [state, dispatch] = useReducer(reducer, { count: 0, step: 1 });
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
### 3. 全局状态管理
|
||||
|
||||
#### Zustand (本项目使用)
|
||||
|
||||
```tsx
|
||||
// ✅ 使用 Zustand
|
||||
import { create } from "zustand";
|
||||
|
||||
interface UserStore {
|
||||
user: User | null;
|
||||
setUser: (user: User) => void;
|
||||
clearUser: () => void;
|
||||
}
|
||||
|
||||
const useUserStore = create<UserStore>(set => ({
|
||||
user: null,
|
||||
setUser: user => set({ user }),
|
||||
clearUser: () => set({ user: null }),
|
||||
}));
|
||||
|
||||
// 使用
|
||||
const UserProfile = () => {
|
||||
const user = useUserStore(state => state.user);
|
||||
const setUser = useUserStore(state => state.setUser);
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
#### Context API
|
||||
|
||||
适用于中等规模的全局状态。
|
||||
|
||||
```tsx
|
||||
// ✅ 使用 Context
|
||||
const UserContext = createContext<UserContextType | null>(null);
|
||||
|
||||
export const UserProvider: React.FC<{ children: React.ReactNode }> = ({
|
||||
children,
|
||||
}) => {
|
||||
const [user, setUser] = useState<User | null>(null);
|
||||
|
||||
return (
|
||||
<UserContext.Provider value={{ user, setUser }}>
|
||||
{children}
|
||||
</UserContext.Provider>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 五、L4 - 样式与CSS策略
|
||||
|
||||
### 1. CSS Modules (推荐)
|
||||
|
||||
本项目使用 **CSS Modules** 配合 **SCSS**。
|
||||
|
||||
```tsx
|
||||
// ✅ 使用 CSS Modules
|
||||
import styles from "./UserProfile.module.scss";
|
||||
|
||||
const UserProfile = () => {
|
||||
return <div className={styles.container}>...</div>;
|
||||
};
|
||||
```
|
||||
|
||||
```scss
|
||||
// UserProfile.module.scss
|
||||
.container {
|
||||
padding: 16px;
|
||||
background-color: #fff;
|
||||
|
||||
.title {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 优势
|
||||
|
||||
- ✅ 样式作用域隔离,避免冲突
|
||||
- ✅ 支持 TypeScript 类型检查
|
||||
- ✅ 支持 SCSS 嵌套和变量
|
||||
- ✅ 构建时优化,自动移除未使用的样式
|
||||
|
||||
### 2. 样式命名规范
|
||||
|
||||
```scss
|
||||
// ✅ 推荐:BEM 命名法
|
||||
.user-profile {
|
||||
&__header {
|
||||
// ...
|
||||
}
|
||||
|
||||
&__body {
|
||||
// ...
|
||||
}
|
||||
|
||||
&__footer {
|
||||
// ...
|
||||
}
|
||||
|
||||
&--active {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 样式变量
|
||||
|
||||
```scss
|
||||
// ✅ 使用 SCSS 变量
|
||||
$primary-color: #1890ff;
|
||||
$secondary-color: #52c41a;
|
||||
$font-size-base: 14px;
|
||||
|
||||
.button {
|
||||
background-color: $primary-color;
|
||||
font-size: $font-size-base;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、L5 - 性能优化指南
|
||||
|
||||
### 1. 避免不必要的重新渲染
|
||||
|
||||
#### 使用 React.memo
|
||||
|
||||
```tsx
|
||||
// ✅ 使用 React.memo 优化子组件
|
||||
const UserItem = React.memo(
|
||||
({ user }: { user: User }) => {
|
||||
return <div>{user.name}</div>;
|
||||
},
|
||||
(prevProps, nextProps) => {
|
||||
// 自定义比较函数
|
||||
return prevProps.user.id === nextProps.user.id;
|
||||
},
|
||||
);
|
||||
```
|
||||
|
||||
#### 使用 useMemo
|
||||
|
||||
```tsx
|
||||
// ✅ 使用 useMemo 缓存计算结果
|
||||
const ExpensiveComponent = ({ items }: { items: Item[] }) => {
|
||||
const sortedItems = useMemo(() => {
|
||||
return items.sort((a, b) => a.price - b.price);
|
||||
}, [items]);
|
||||
|
||||
return <div>{/* 使用 sortedItems */}</div>;
|
||||
};
|
||||
```
|
||||
|
||||
#### 使用 useCallback
|
||||
|
||||
```tsx
|
||||
// ✅ 使用 useCallback 缓存函数
|
||||
const Parent = () => {
|
||||
const [count, setCount] = useState(0);
|
||||
|
||||
const handleClick = useCallback(() => {
|
||||
setCount(prev => prev + 1);
|
||||
}, []);
|
||||
|
||||
return <Child onClick={handleClick} />;
|
||||
};
|
||||
```
|
||||
|
||||
### 2. 代码分割与懒加载 (Lazy Loading)
|
||||
|
||||
```tsx
|
||||
// ✅ 使用 React.lazy 和 Suspense
|
||||
import { lazy, Suspense } from "react";
|
||||
|
||||
const UserProfile = lazy(() => import("./pages/UserProfile"));
|
||||
|
||||
const App = () => {
|
||||
return (
|
||||
<Suspense fallback={<LoadingSpinner />}>
|
||||
<UserProfile />
|
||||
</Suspense>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
### 3. 列表渲染优化
|
||||
|
||||
#### 虚拟列表
|
||||
|
||||
对于长列表,使用虚拟滚动。
|
||||
|
||||
```tsx
|
||||
// ✅ 使用虚拟列表组件
|
||||
import { FixedSizeList } from "react-window";
|
||||
|
||||
const VirtualizedList = ({ items }: { items: Item[] }) => {
|
||||
return (
|
||||
<FixedSizeList
|
||||
height={600}
|
||||
itemCount={items.length}
|
||||
itemSize={50}
|
||||
width="100%"
|
||||
>
|
||||
{({ index, style }) => (
|
||||
<div style={style}>
|
||||
<Item item={items[index]} />
|
||||
</div>
|
||||
)}
|
||||
</FixedSizeList>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 七、L6 - 项目结构与架构
|
||||
|
||||
### 1. 功能分区目录结构 (Feature-Based Structure)
|
||||
|
||||
本项目采用功能分区 + 类型分区的混合结构:
|
||||
|
||||
```
|
||||
src/
|
||||
├── components/ # 通用组件(可复用)
|
||||
│ ├── Button/
|
||||
│ ├── Modal/
|
||||
│ └── ...
|
||||
├── pages/ # 页面组件(路由级别)
|
||||
│ ├── Home/
|
||||
│ ├── Profile/
|
||||
│ └── ...
|
||||
├── hooks/ # 自定义 Hooks
|
||||
│ ├── useAuth.ts
|
||||
│ └── useLocalStorage.ts
|
||||
├── utils/ # 工具函数
|
||||
│ ├── formatDate.ts
|
||||
│ └── validate.ts
|
||||
├── store/ # 状态管理(Zustand)
|
||||
│ ├── module/
|
||||
│ │ ├── user.ts
|
||||
│ │ └── weChat.ts
|
||||
│ └── index.ts
|
||||
├── api/ # API 接口
|
||||
│ ├── request.ts
|
||||
│ └── module/
|
||||
│ └── wechat.ts
|
||||
├── types/ # TypeScript 类型定义
|
||||
│ ├── user.ts
|
||||
│ └── weChat.ts
|
||||
└── router/ # 路由配置
|
||||
├── index.tsx
|
||||
└── module/
|
||||
```
|
||||
|
||||
### 2. 使用绝对路径导入
|
||||
|
||||
本项目已配置路径别名 `@` 指向 `src` 目录。
|
||||
|
||||
```tsx
|
||||
// ✅ 使用绝对路径
|
||||
import { Button } from "@/components/Button";
|
||||
import { useUserStore } from "@/store/module/user";
|
||||
import { formatDate } from "@/utils/formatDate";
|
||||
|
||||
// ❌ 避免相对路径
|
||||
import { Button } from "../../../components/Button";
|
||||
```
|
||||
|
||||
### 3. 组件导出规范
|
||||
|
||||
```tsx
|
||||
// ✅ 推荐:使用 index.ts 统一导出
|
||||
// components/Button/index.tsx
|
||||
export { default } from "./Button";
|
||||
export type { ButtonProps } from "./types";
|
||||
|
||||
// 使用
|
||||
import Button from "@/components/Button";
|
||||
import type { ButtonProps } from "@/components/Button";
|
||||
```
|
||||
|
||||
### 4. 类型定义规范
|
||||
|
||||
```tsx
|
||||
// ✅ 类型定义文件
|
||||
// types/user.ts
|
||||
export interface User {
|
||||
id: number;
|
||||
name: string;
|
||||
email: string;
|
||||
}
|
||||
|
||||
export type UserRole = "admin" | "user" | "guest";
|
||||
|
||||
// 使用
|
||||
import type { User, UserRole } from "@/types/user";
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 总结
|
||||
|
||||
### 核心原则
|
||||
|
||||
1. **一致性**:保持代码风格和命名规范的一致性
|
||||
2. **可读性**:代码应该易于理解和维护
|
||||
3. **可复用性**:组件和函数应该尽可能可复用
|
||||
4. **性能**:关注性能优化,但不要过度优化
|
||||
5. **类型安全**:充分利用 TypeScript 的类型检查
|
||||
|
||||
### 检查清单
|
||||
|
||||
在提交代码前,确保:
|
||||
|
||||
- [ ] 组件命名符合 PascalCase
|
||||
- [ ] 函数命名符合 camelCase
|
||||
- [ ] 使用了 TypeScript 类型定义
|
||||
- [ ] 样式使用了 CSS Modules
|
||||
- [ ] 避免了不必要的重新渲染
|
||||
- [ ] 使用了绝对路径导入
|
||||
- [ ] 代码通过了 ESLint 检查
|
||||
- [ ] 代码通过了 Prettier 格式化
|
||||
|
||||
### 参考资源
|
||||
|
||||
- [React 官方文档](https://react.dev/)
|
||||
- [TypeScript 官方文档](https://www.typescriptlang.org/)
|
||||
- [Zustand 文档](https://zustand-demo.pmnd.rs/)
|
||||
- [CSS Modules 文档](https://github.com/css-modules/css-modules)
|
||||
|
||||
---
|
||||
|
||||
**最后更新**: 2025-01-XX
|
||||
**维护者**: 开发团队
|
||||
@@ -1,4 +1,5 @@
|
||||
## 使用技术栈
|
||||
|
||||
- React 18
|
||||
- TypeScript
|
||||
- Vite(新一代前端构建工具)
|
||||
@@ -12,15 +13,22 @@
|
||||
- 路径别名 @ 指向 src 目录
|
||||
|
||||
## 关于兼容与工程化
|
||||
|
||||
- 自动化脚本(yarn lint、yarn dev 等)
|
||||
- 移动端 rem 适配(html 根字体 + pxtorem)
|
||||
- iOS 浏览器滚动回弹兼容问题已通过全局样式处理
|
||||
- 支持 VS Code 编辑器自动格式化(推荐配合 ESLint/Prettier 插件)
|
||||
|
||||
## 目录结构简要
|
||||
|
||||
- src/ 业务源码(pages、api、styles、App.tsx、main.tsx 等)
|
||||
- public/ 静态资源目录
|
||||
- index.html 项目入口(根目录)
|
||||
- vite.config.ts 构建与路径别名配置
|
||||
- tsconfig.json TypeScript 配置
|
||||
- .eslintrc.js 代码规范配置
|
||||
- .eslintrc.js 代码规范配置
|
||||
|
||||
## 新增优化组件
|
||||
|
||||
TanStack Query
|
||||
Sentry
|
||||
|
||||
Reference in New Issue
Block a user