在 React 开发中,一个清晰合理的项目结构不仅能提高开发效率,还能让代码更易于维护和扩展。尤其是在团队协作中,统一的项目结构规范至关重要。本文将通过图文结合的方式,详细介绍 React 项目的基本框架以及常见文件夹的定义与作用。
一、React 项目基本框架
一个典型的 React 项目结构通常如下(以 create-react-app 创建的项目为基础):
my-react-app/
├── public/ 📁 静态资源目录
├── src/ 📁 源代码目录
│ ├── components/ 🧩 公共组件
│ ├── pages/ 📄 页面组件
│ ├── hooks/ 🔧 自定义Hooks
│ ├── utils/ 🛠️ 工具函数
│ ├── assets/ 📊 资源文件
│ ├── services/ 🌐 API服务
│ ├── context/ 🧬 上下文
│ ├── redux/ 🗃️ 状态管理
│ ├── routes/ 🚦 路由配置
│ ├── config/ ⚙️ 配置文件
│ ├── App.js 🏠 根组件
│ └── index.js 🚀 入口文件
├── package.json 📦 项目配置
└── README.md 📖 项目说明
下图展示了 React 项目各部分的关系:
┌─────────────────────────────────────────────────────────┐
│ public/ │
│ (静态资源,不被Webpack处理) │
└───────────────────────────┬─────────────────────────────┘
│
┌───────────────────────────▼─────────────────────────────┐
│ src/ │
│ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
│ │components/│ │ pages/ │ │ hooks/ │ │ utils/ │ │
│ │ (组件) │ │ (页面) │ │(自定义钩子)│ │ (工具函数)│ │
│ └───────────┘ └───────────┘ └───────────┘ └───────────┘ │
│ │
│ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
│ │ assets/ │ │ services/ │ │ context/ │ │ redux/ │ │
│ │ (资源) │ │ (API) │ │(上下文) │ │(状态管理) │ │
│ └───────────┘ └───────────┘ └───────────┘ └───────────┘ │
│ │
│ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
│ │ routes/ │ │ config/ │ │ App.js │ │ index.js │ │
│ │ (路由) │ │ (配置) │ │ (根组件) │ │ (入口) │ │
│ └───────────┘ └───────────┘ └───────────┘ └───────────┘ │
└─────────────────────────────────────────────────────────┘
二、常见文件夹定义与作用
1. public/
- 作用:存放静态资源,这些资源不会被 Webpack 处理
- 包含内容 :
- index.html:应用的入口 HTML 文件
- favicon.ico:网站图标
- robots.txt:搜索引擎爬虫规则
- 其他静态文件(如无需编译的 JS、CSS)
示意图:
public/
├── index.html 🌐 应用入口页面
├── favicon.ico 🔍 网站图标
├── robots.txt 🤖 爬虫规则
└── manifest.json 📱 PWA配置文件
2. src/
- 作用:存放所有源代码,是开发的主要工作目录
- 所有 JavaScript、CSS、图片等资源都建议放在此目录下,会被 Webpack 处理
3. components/
- 作用:存放可复用的公共组件
- 特点 :
- 不依赖路由,可在多个页面中复用
- 通常是 UI 组件,如按钮、表单、卡片等
- 可以按功能进一步细分,如
components/buttons/
、components/forms/
组件关系示意图:
页面组件 (pages/)
↓ ↓ ↓
组件A 组件B 组件C (components/)
↘ ↓ ↙
基础组件 (如Button)
// 示例:components/Button/Button.jsx
import React from 'react';
import './Button.css';
const Button = ({ text, onClick, type = 'primary' }) => {
return (
<button
className={`custom-button custom-button-${type}`}
onClick={onClick}
>
{text}
</button>
);
};
export default Button;
4. pages/
- 作用:存放页面级组件,对应路由配置的页面
- 特点 :
- 通常与路由一一对应
- 可以包含多个 components 中的组件
- 可能会包含页面级别的业务逻辑
页面结构示意图:
pages/
├── Home/ 🏠 首页
├── About/ 👋 关于页
├── Products/ 🛒 产品页
│ ├── index.jsx 📄 产品列表页
│ └── Detail.jsx 🔍 产品详情页
└── User/ 👤 用户相关页面
├── Login.jsx 🔑 登录页
└── Profile.jsx 🧑💼 个人资料页
5. hooks/
- 作用:存放自定义 React Hook
- 特点 :
-
封装可复用的状态逻辑
-
文件名通常以
use
开头(如 useAuth.js、useFetch.js) -
使函数组件能够使用状态和其他 React 特性
// 示例:hooks/useFetch.js
import { useState, useEffect } from 'react';const useFetch = (url) => {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);useEffect(() => {
// 清除函数,用于组件卸载时
const abortController = new AbortController();fetch(url, { signal: abortController.signal }) .then(res => res.json()) .then(data => { setData(data); setLoading(false); }) .catch(err => { if (err.name !== 'AbortError') { setError(err); setLoading(false); } }); return () => abortController.abort();
}, [url]);
return { data, loading, error };
};export default useFetch;
-
6. utils/
- 作用:存放工具函数和辅助方法
- 包含内容 :
- 日期格式化函数
- 数据验证函数
- 本地存储工具
- 通用计算函数等
工具函数分类:
utils/
├── formatters/ 📅 格式化工具(日期、货币等)
├── validators/ ✅ 验证工具(表单验证等)
├── storage.js 💾 本地存储工具
└── helpers.js 🛠️ 通用辅助函数
7. assets/
- 作用:存放静态资源文件
- 包含内容 :
- 图片(jpg、png、svg 等)
- 字体文件
- 全局样式文件
- 图标文件等
资源文件组织:
assets/
├── images/ 🖼️ 图片资源
├── fonts/ 🔤 字体文件
├── styles/ 🎨 样式文件
│ ├── global.css 🖌️ 全局样式
│ └── variables.css 🎨 样式变量
└── icons/ 🏷️ 图标资源
8. services/
- 作用:存放 API 请求相关代码
- 特点 :
- 封装与后端的交互逻辑
- 集中管理接口地址
- 便于统一处理请求 / 响应拦截器
API 服务流程图:
组件 (components/pages)
↓
调用API方法 (services)
↓
使用axios/fetch发送请求
↓
后端服务器
↓
返回响应数据
↓
处理并返回给组件
// 示例:services/userService.js
import axios from 'axios';
import { API_BASE_URL } from '../config';
// 创建axios实例
const api = axios.create({
baseURL: API_BASE_URL,
timeout: 5000,
headers: {
'Content-Type': 'application/json'
}
});
// 请求拦截器
api.interceptors.request.use(
config => {
// 可以在这里添加token等
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
error => Promise.reject(error)
);
// 获取用户信息
const getUserInfo = async (userId) => {
try {
const response = await api.get(`/users/${userId}`);
return response.data;
} catch (error) {
console.error('获取用户信息失败:', error);
throw error;
}
};
export default { getUserInfo };
9. context/
- 作用:存放 React Context 相关文件
- 作用:解决组件层级较深时的状态传递问题,避免 props drilling
Context 工作流程:
创建Context
↓
Provider提供数据
↓
中间组件(无需传递props)
↓
Consumer使用数据
10. redux/ 或 store/
- 作用:存放状态管理相关代码(使用 Redux、Redux Toolkit 等)
- 通常包含 :
- actions:动作创建器
- reducers:状态 reducer
- store.js:Redux store 配置
- slices:使用 Redux Toolkit 时的切片
Redux 数据流:
UI组件 → 触发Action → Reducer处理 → 更新Store → UI重新渲染
11. routes/
- 作用:存放路由配置相关代码
- 特点 :
- 集中管理应用的路由规则
- 通常与 pages 文件夹中的组件对应
路由配置示例:
// routes/index.jsx
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Home from '../pages/Home';
import About from '../pages/About';
import ProductList from '../pages/Products';
import ProductDetail from '../pages/Products/Detail';
import NotFound from '../pages/NotFound';
import Layout from '../components/Layout';
const AppRoutes = () => {
return (
<BrowserRouter>
<Layout>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/products" element={<ProductList />} />
<Route path="/products/:id" element={<ProductDetail />} />
<Route path="*" element={<NotFound />} />
</Routes>
</Layout>
</BrowserRouter>
);
};
export default AppRoutes;
12. config/
- 作用:存放配置文件
- 包含内容 :
- 环境变量配置
- 全局常量
- API 基础地址
- 主题配置等
三、项目结构设计原则
- 单一职责:每个文件和文件夹应专注于单一功能
- 可复用性:提取公共逻辑到 hooks、utils 和 components
- 可扩展性:预留未来功能扩展的空间
- 一致性:保持命名和结构的一致性
- 按需调整:根据项目规模和团队情况灵活调整结构
四、不同规模项目的结构调整
-
小型项目:可以简化结构,合并一些文件夹
-
中型项目:使用上述标准结构
-
大型项目:可能需要更细致的划分,如按业务模块组织代码
// 大型项目可能的结构(按业务模块)
src/
├── features/ 🌟 业务功能模块
│ ├── auth/ 🔑 认证相关
│ ├── products/ 🛒 产品相关
│ └── user/ 👤 用户相关
├── shared/ 🤝 共享资源
│ ├── components/ 🧩 公共组件
│ ├── hooks/ 🔧 公共钩子
│ └── utils/ 🛠️ 工具函数
└── app/ 🏠 应用核心
├── routes/ 🚦 路由
├── store/ 🗃️ 状态管理
└── App.js 根组件
五、总结
合理的项目结构是 React 应用开发的基础,它能显著提高代码的可维护性和团队协作效率。上述结构是大多数 React 项目的通用方案,实际开发中可以根据项目规模、团队习惯和业务需求进行适当调整。记住,没有放之四海而皆准的完美结构,最重要的是保持团队内部的一致性和代码的清晰可读。随着项目的发展,也可以逐步优化和重构项目结构,使其更好地服务于业务开发。希望本文的图文介绍能帮助你更好地理解和组织 React 项目结构!
本文是「前端基础知识系列」的第六篇,聚焦React 项目基本框架。后续将持续更新前端开发必备基础知识。关注作者,每天掌握一个前端基础知识,逐步构建完整的技术体系~