bulletproof-react-patterns

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Bulletproof React Patterns

Bulletproof React 架构模式

Architecture patterns for building scalable, maintainable React applications. Based on bulletproof-react.
用于构建可扩展、易维护的 React 应用的架构模式。基于 bulletproof-react。

Core References

核心参考

TopicDescriptionReference
Project StructureFeature-based organization, unidirectional architecture, ESLint enforcementproject-structure
Components & StylingComponent hierarchy, wrapping 3rd party libs, headless vs styled librariescomponents-and-styling
API LayerAPI client, request declarations, query/mutation hook patternsapi-layer
State ManagementComponent, application, server cache, form, and URL state categoriesstate-management
Error HandlingError boundaries, API errors, error tracking with Sentryerror-handling
TestingUnit, integration, e2e strategies with Vitest, Testing Library, Playwright, MSWtesting
Project StandardsESLint, Prettier, TypeScript, Husky, absolute imports, file namingproject-standards
SecurityAuthentication, token storage, XSS prevention, RBAC/PBAC authorizationsecurity
PerformanceCode splitting, data prefetching, state optimization, children patternperformance
主题描述参考
项目结构基于功能的组织方式、单向架构、ESLint 约束project-structure
组件与样式组件层级、封装第三方库、headless 库与 styled 库的取舍components-and-styling
API 层API 客户端、请求声明、query/mutation hook 模式api-layer
状态管理组件状态、应用状态、服务器缓存、表单状态和 URL 状态分类state-management
错误处理Error Boundary、API 错误、使用 Sentry 进行错误追踪error-handling
测试使用 Vitest、Testing Library、Playwright、MSW 进行单元、集成和 E2E 测试testing
项目规范ESLint、Prettier、TypeScript、Husky、绝对路径导入、文件命名project-standards
安全身份验证、令牌存储、XSS 防护、RBAC/PBAC 授权security
性能代码拆分、数据预取、状态优化、children 模式performance

Project Structure

项目结构

Organize by feature, not by file type:
src/
├── app/                # Application shell (routes, providers, router)
├── assets/             # Static files (images, fonts)
├── components/         # Shared, reusable UI components
├── config/             # Environment variables, constants
├── features/           # Feature-based modules
├── hooks/              # Shared custom hooks
├── lib/                # Pre-configured library wrappers
├── stores/             # Global client state
├── testing/            # Test utilities, MSW handlers, factories
├── types/              # Shared TypeScript types
└── utils/              # Pure utility functions
按功能组织,而不是按文件类型组织:
src/
├── app/                # Application shell (routes, providers, router)
├── assets/             # Static files (images, fonts)
├── components/         # Shared, reusable UI components
├── config/             # Environment variables, constants
├── features/           # Feature-based modules
├── hooks/              # Shared custom hooks
├── lib/                # Pre-configured library wrappers
├── stores/             # Global client state
├── testing/            # Test utilities, MSW handlers, factories
├── types/              # Shared TypeScript types
└── utils/              # Pure utility functions

Feature Modules

功能模块

features/users/
├── api/            # API functions and query hooks
├── components/     # Feature-specific components
├── hooks/          # Feature-specific hooks
├── types/          # Feature-specific types
└── utils/          # Feature-specific utilities
Rules:
  • Features should not import from other features. Compose at the app level.
  • Code flows one direction: shared → features → app.
  • Promote to shared directories only when reused by 2+ features.
  • Prefer direct imports over barrel re-exports for Vite tree-shaking.
features/users/
├── api/            # API functions and query hooks
├── components/     # Feature-specific components
├── hooks/          # Feature-specific hooks
├── types/          # Feature-specific types
└── utils/          # Feature-specific utilities
规则:
  • 功能模块不应导入其他功能模块中的内容,应在 app 层进行组合。
  • 代码应单向流动:shared → features → app。
  • 只有在内容被 2 个及以上功能复用时,才将其提升到 shared 目录。
  • 为实现 Vite tree-shaking,应优先直接导入,而非通过 barrel 文件重新导出。

Component Hierarchy

组件层级

Page Components          → route-level, compose features, handle layout
  └── Feature Components → feature-specific, business logic
        └── UI Components      → shared primitives, no business logic
Page Components          → route-level, compose features, handle layout
  └── Feature Components → feature-specific, business logic
        └── UI Components      → shared primitives, no business logic

API Layer Pattern

API 层模式

typescript
// Pure API function
function getUsers(params?: GetUsersParams): Promise<UsersResponse> {
    return api.get("/users", { params });
}

// Query hook wrapping the API function
function useUsers(params?: GetUsersParams) {
    return useQuery({
        queryKey: ["users", params],
        queryFn: () => getUsers(params),
    });
}
typescript
// Pure API function
function getUsers(params?: GetUsersParams): Promise<UsersResponse> {
    return api.get("/users", { params });
}

// Query hook wrapping the API function
function useUsers(params?: GetUsersParams) {
    return useQuery({
        queryKey: ["users", params],
        queryFn: () => getUsers(params),
    });
}

State Management Boundaries

状态管理边界

State TypeSolutionExamples
Server stateTanStack QueryUser data, posts, API responses
Client state (global)Zustand / JotaiTheme, sidebar open, user preferences
Client state (local)useState / useReducerForm inputs, toggles, modal open
URL stateURL search params / routerFilters, pagination, active tab
Form stateReact Hook FormMulti-step forms, validation
Don't mix server and client state. Never copy query data into
useState
.
状态类型解决方案示例
服务器状态TanStack Query用户数据、帖子、API 响应
客户端状态(全局)Zustand / Jotai主题、侧边栏展开状态、用户偏好
客户端状态(局部)useState / useReducer表单输入、开关、弹窗打开状态
URL 状态URL search params / router筛选器、分页、当前标签页
表单状态React Hook Form多步骤表单、验证
不要混合服务器状态和客户端状态。 永远不要将 query 数据复制到
useState
中。

Error Hierarchy

错误层级

App Error Boundary          → catches unrecoverable crashes
  └── Route Error Boundary     → catches route-level failures, shows retry
        └── Feature Error Boundary   → catches feature-specific errors
App Error Boundary          → catches unrecoverable crashes
  └── Route Error Boundary     → catches route-level failures, shows retry
        └── Feature Error Boundary   → catches feature-specific errors

Testing Strategy

测试策略

LayerToolWhat to Test
ComponentsTesting LibraryRender output, user interactions, a11y
HooksrenderHookState changes, side effects
APIMSWRequest/response handling, error states
IntegrationTesting Library + MSWFull feature flows (render → interact → verify)
E2EPlaywrightCritical user journeys
层级工具测试内容
组件Testing Library渲染输出、用户交互、a11y
HooksrenderHook状态变化、副作用
APIMSW请求/响应处理、错误状态
集成Testing Library + MSW完整功能流程(渲染 → 交互 → 验证)
E2EPlaywright关键用户旅程

Conventions

约定

ItemConventionExample
ComponentsPascalCase
UserCard.tsx
HookscamelCase,
use
prefix
useUsers.ts
UtilitiescamelCase
formatDate.ts
TypesPascalCase
User
,
CreateUserInput
ConstantsUPPER_SNAKE_CASE
MAX_RETRIES
Directorieskebab-case
user-settings/
Fileskebab-case
user-card.tsx
项目约定示例
组件PascalCase
UserCard.tsx
HookscamelCase、
use
前缀
useUsers.ts
工具函数camelCase
formatDate.ts
类型PascalCase
User
、
CreateUserInput
常量UPPER_SNAKE_CASE
MAX_RETRIES
目录kebab-case
user-settings/
文件kebab-case
user-card.tsx

Imports

导入

Use path aliases to avoid deep relative imports:
typescript
import { Button } from "@/components/ui/button";
import { useUsers } from "@/features/users/api";
Configure
@/
as the
src/
alias in
tsconfig.json
.
使用路径别名,避免深层相对路径导入:
typescript
import { Button } from "@/components/ui/button";
import { useUsers } from "@/features/users/api";
在
tsconfig.json
中将
@/
配置为
src/
的别名。