React 项目架构基础
在现代前端开发中,React 项目早已不只是“写几个组件”这么简单。一个清晰、可扩展的项目架构,决定了开发效率、维护成本以及后期演进能力。本文将结合 Vite + React + React Router 的实际代码,梳理 React 项目的基础架构。
一、项目初始化与脚手架选择
1. 使用 Vite 初始化项目
-
npm init vite: 使用 Vite 作为项目初始化工具,Vite 是一个现代前端构建工具,支持快速冷启动(cold start)和 ESM(ECMAScript Modules)模块化。Vite 专注于开发阶段的快速迭代,内置了对 React 的支持。
-
从 GitHub 拉取项目模板: 通过 GitHub 下载预配置的项目模板,以加速项目启动,避免从零搭建。
-
npm run dev: 运行开发服务器,启动开发模式(dev),用于本地调试和热重载(hot module replacement)。
Vite 是当前主流的前端构建工具之一,它的核心优势在于:
- 基于 ESM(ECMAScript Modules) 的模块加载
- 天然适配 React、Vue 等现代框架
Vite 更关注 开发阶段的效率,通过按需加载模块,避免传统打包工具在启动时的全量编译。
2. 项目开发的生命周期
一个典型的前端项目通常经历以下阶段:
- dev(开发阶段) :本地调试、热更新
- test(测试阶段) :单元测试、集成测试
- production(生产阶段) :构建优化后的代码并部署上线
整体呈现一个不断迭代的循环:
dev → test → production → dev → …
二、依赖管理与模块化规范
1. devDependencies 与 dependencies
-
devDependencies(开发依赖)
-
只在开发期间使用
-
示例:
vite:开发脚手架stylus:CSS 预处理器(由 Vite 自动编译)
-
npm i -D stylus
-
dependencies(项目依赖)
-
项目运行时必须存在
-
核心依赖:
react@19.2.0react-dom@19.2.0
-
React 负责组件与状态逻辑,React DOM 负责将组件渲染到浏览器 DOM,可以类比为:
Vue ≈ React(核心) + React DOM(渲染层)
2. 模块化标准
-
ESM(推荐)
import / export- 支持 Tree Shaking、按需加载
-
CJS(旧标准)
require / module.exports- 常见于 Node.js 早期生态
Vite 默认采用 ESM,这是实现极速启动的重要基础。
三、前端路由管理:React Router
1. 安装路由库
npm i react-router-dom
React Router 是 React 生态中事实上的路由标准。
2. 路由模式选择
-
BrowserRouter
- 基于 HTML5 History API
- URL 干净(如
/about) - 需要后端支持 SPA 路由回退
-
HashRouter
- 使用
#/about - 兼容性好
- URL 形式较早期、略显冗余
- 使用
import { BrowserRouter as Router } from 'react-router-dom'
as 用于起别名,提升可读性。
3. 路由核心组件
Router:路由接管入口Routes:路由规则总管Route:单个路由实例Link:替代<a>的导航组件(避免页面刷新)
四、入口文件与应用挂载流程
1. main.jsx:项目入口文件
import { createRoot } from 'react-dom/client'
import App from './App.jsx'
createRoot(document.getElementById('root')).render(
<App />
)
createRoot:React 18+ 引入的并发渲染入口render:将 React 组件树挂载到真实 DOM
在开发模式下,React 会执行两次渲染,用于 StrictMode 的安全审查(review) 。
五、App 根组件,包裹路由和导航
import { BrowserRouter as Router, Link } from 'react-router-dom'
import AppRouters from './router'
function App() {
return (
<Router>
<nav>
<ul>
<li><Link to="/Home">Home</Link></li>
<li><Link to="/About">About</Link></li>
</ul>
</nav>
<AppRouters />
</Router>
)
}
export default App
关键点:
<a>标签不再直接使用,否则会触发页面刷新Link内部通过路由系统“消化跳转”App作为根组件,负责导航与路由容器
六、路由配置拆分:router/index.jsx
import { Routes, Route } from 'react-router-dom'
import Home from '../pages/Home'
import About from '../pages/About'
export default function AppRouters() {
return (
<Routes>
<Route path="/" element={<Home />} />
<Route path="about" element={<About />} />
</Routes>
)
}
这种拆分方式可以让:
- 路由逻辑独立于 UI
- 项目结构更加清晰
- 后期更容易做权限路由、懒加载
七、页面组件与 Hooks 使用
1. 函数组件是 React 的主流形式
const About = () => {
return (
<div>
<h1>About</h1>
</div>
)
}
// esm
export default About
2. Hooks:组件能力的来源
useState —— 响应式状态
const [repos, setRepos] = useState([])
类似于 Vue 的 ref / reactive。
useEffect —— 副作用管理
useEffect(() => {
fetch('https://api.github.com/users/.../repos')
.then(res => res.json())
.then(data => setRepos(data))
}, []) //useEffect(() => { ... }, []) 中的 [](空依赖数组)正是为了确保副作用函数只运行一次,并且这个**一次**具体发生在组件首次挂载(mount)完成后,这与 Vue 中的 onMounted 生命周期钩子完全等价。
-
在组件渲染完成后执行
-
常用于:
- 请求接口
- 订阅 / 清理资源
render 永远是第一位的,副作用不会阻塞渲染。
八、条件渲染与列表渲染
return (
<div>
<h1>Home</h1>
{
repos.length ? (
<ul>
{
repos.map(repo => (
<li key={repo.id}>
<a href={repo.html_url} target="_blank" rel="noreferrer">
{repo.name}
</a>
</li>
))
}
</ul>
) : (
<p>暂无仓库</p>
)
}
</div>
)
}
- 条件渲染:三元表达式
- 列表渲染:
map key:用于提升 React Diff 算法性能