服务和修改React 生态系统提供了多个出色的起点,每个起点都适合不同的项目要求。创建 React 应用程序 (CRA)
CRA 是最初的首选引导工具。它在底层提供了 Webpack 的零配置设置。但是,它不再被积极维护,也不建议用于新项目。
Vite
Vite已成为单页应用的首选。它提供极快的热模块更换 (HMR) 和由 Rollup 支持的精益构建流程。
npm create vite@latest my-app -- --template react
cd my-app
npm install
npm run dev
Next.js
对于需要服务器端渲染 (SSR)、静态站点生成 (SSG) 或 API 路由的应用程序,Next.js 是行业标准。它提供基于文件的路由、内置图像优化和开箱即用的出色性能。
npx create-next-app@latest my-app
cd my-app
npm run dev
选择 Vite 来实现纯 SPA 和客户端渲染的仪表板。当您需要 SEO、SSR 或全栈框架时,请选择 Next.js。
3. 组件架构和组成
结构良好的组件是可维护的 React 应用的基础。 请遵循以下原则:
- 单一职责- 每个组件都应该做好一件事
- 组合胜于继承- 通过组合简单组件构建复杂的 UI
- 容器/演示分离- 将数据获取逻辑与渲染分开
- 托管- 将相关文件(组件、样式、测试、类型)放在一起
推荐的项目结构如下所示:
src/
components/
Button/
Button.jsx
Button.test.jsx
Button.module.css
index.js
Header/
Header.jsx
Header.test.jsx
features/
auth/
LoginForm.jsx
useAuth.js
authSlice.js
dashboard/
Dashboard.jsx
DashboardCard.jsx
hooks/
useLocalStorage.js
useDebounce.js
utils/
formatDate.js
api.js
4. React Hooks 深入研究
Hook 是现代 React 开发的支柱。深入理解它们对于构建强大的应用程序至关重要。
useState 和 useReducer
使用useState获得简单、独立的状态值。当状态逻辑变得复杂或下一个状态依赖于前一个状态时,切换到useReducer。
import { useReducer } from 'react';
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
throw new Error('Unknown action');
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
</div>
);
}
useEffect 和 useLayoutEffect
使用useEffect实现数据获取、订阅和 DOM 突变等副作用。仅当您需要在浏览器绘制之前测量或改变 DOM 时,才使用useLayoutEffect。
useMemo 和 useCallback
这些挂钩分别记忆值和函数。在将回调传递给优化的子组件或计算昂贵的派生值时使用它们。不要过度使用它们 - 过早的优化会增加复杂性,而不会带来可衡量的好处。
自定义挂钩
将可重用逻辑提取到自定义挂钩中。这是 React 最强大的模式之一:
function useLocalStorage(key, initialValue) {
const [value, setValue] = useState(() => {
const stored = localStorage.getItem(key);
return stored ? JSON.parse(stored) : initialValue;
});
useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
return [value, setValue];
}
5. 状态管理
选择正确的状态管理方法取决于应用程序的复杂性。
React 上下文
上下文内置于 React 中,适用于主题、身份验证状态和区域设置等低频更新。避免将其用于频繁更改的数据,因为每个消费者都会在每次上下文值更改时重新渲染。
Redux 工具套件
Redux 工具套件极大地简化了 Redux。它是具有复杂互连状态的大型应用程序的最佳选择:
import { createSlice, configureStore } from '@reduxjs/toolkit';
const todosSlice = createSlice({
name: 'todos',
initialState: [],
reducers: {
addTodo: (state, action) => {
state.push({ id: Date.now(), text: action.payload, done: false });
},
toggleTodo: (state, action) => {
const todo = state.find(t => t.id === action.payload);
if (todo) todo.done = !todo.done;
},
},
});
export const store = configureStore({
reducer: { todos: todosSlice.reducer },
});
Zustand
Zustand 提供了一个轻量级、基于钩子的存储,并且具有最少的样板。它非常适合中型应用:
import { create } from 'zustand';
const useStore = create((set) => ({
count: 0,
increment: () => set((s) => ({ count: s.count + 1 })),
decrement: () => set((s) => ({ count: s.count - 1 })),
}));
6. 使用 React 路由器进行路由
对于 SPA,React 路由器提供声明式路由。版本 6 引入了带有嵌套路由和相关链接的简化 API:
import { BrowserRouter, Routes, Route } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/dashboard" element={<Dashboard />}>
<Route path="analytics" element={<Analytics />} />
<Route path="settings" element={<Settings />} />
</Route>
<Route path="*" element={<NotFound />} />
</Routes>
</BrowserRouter>
);
}
对于 Next.js 项目,路由是基于文件系统的,您根本不需要 React 路由器。
7. API 与 React 查询集成
TanStack 查询(以前称为 React 查询)是服务器状态管理的标准。它处理缓存、后台重新获取、分页和乐观更新:
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
function useTodos() {
return useQuery({
queryKey: ['todos'],
queryFn: () => fetch('/api/todos').then(res => res.json()),
staleTime: 5 * 60 * 1000,
});
}
function useAddTodo() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (newTodo) =>
fetch('/api/todos', {
method: 'POST',
body: JSON.stringify(newTodo),
}),
onSuccess: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),
});
}
8. 表单处理
对于超出简单输入的表单,请使用表单库。 React Hook Form 重量轻且高性能:
import { useForm } from 'react-hook-form';
function SignupForm() {
const { register, handleSubmit, formState: { errors } } = useForm();
const onSubmit = (data) => console.log(data);
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register('email', { required: 'Email is required' })} />
{errors.email && <span>{errors.email.message}</span>}
<input type="password" {...register('password', { minLength: 8 })} />
<button type="submit">Sign Up</button>
</form>
);
}
9. 使用 Jest 和 React 测试库进行测试
测试可确保您的应用程序正常工作并在您进行更改时继续工作。 React 测试库鼓励以用户与其交互的方式测试组件:
import { render, screen, fireEvent } from '@testing-library/react';
import Counter from './Counter';
test('increments counter on button click', () => {
render(<Counter />);
const button = screen.getByRole('button', { name: /increment/i });
fireEvent.click(button);
expect(screen.getByText(/count: 1/i)).toBeInTheDocument();
});
围绕用户行为而不是实现细节构建测试。测试用户所看到和所做的事情,而不是内部组件状态。
10. CI/CD 管道
使用 CI/CD 管道自动化构建、测试和部署过程。 React 应用程序的典型 GitHub Actions 工作流程:
name: CI/CD
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- run: npm ci
- run: npm run lint
- run: npm test -- --coverage
- run: npm run build
11. 部署
部署位置取决于您的框架选择和基础设施要求。
Vercel
Vercel 是 Next.js 应用的最简单选择。连接您的 Git 存储库,Vercel 会自动处理构建、预览和生产部署。每个拉取请求都会获得一个预览 URL。
AWS
如需更多控制,请使用 S3 + CloudFront(用于静态 SPA)或 ECS/Fargate(用于服务器渲染应用程序)等服务部署到 AWS。 AWS Amplify 提供与 Vercel 类似的托管托管体验。
Docker
将您的应用程序容器化,以实现跨环境的一致部署:
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:20-alpine AS runner
WORKDIR /app
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./
EXPOSE 3000
CMD ["npm", "start"]
12. 性能监控
应用程序投入生产后,请监控其性能以尽早发现回归情况。
- 核心 Web Vitals- 使用 Google Lighthouse 或
web-vitals库等工具跟踪 LCP、FID 和 CLS - 错误跟踪- 使用 Sentry 或 Bugsnag 捕获和诊断运行时错误
- 分析- 实施事件跟踪以了解用户行为
- 捆绑包分析- 运行
npx webpack-bundle-analyzer或npx vite-bundle-visualizer以识别较大的依赖性
React DevTools Profiler 可帮助识别开发期间不必要的重新渲染。有策略地使用React.memo、useMemo和useCallback来优化热路径。
结论
构建生产型 React 应用程序是一个经历规划、架构、实施、测试和部署的过程。每个阶段都建立在前一个阶段的基础上。从一个可靠的计划开始,根据您的要求选择正确的工具,编写干净且可组合的组件,彻底测试,自动化您的管道,并在生产中进行监控。 React 生态系统成熟且得到良好支持 - 利用其优势,您将充满信心地交付可靠、高性能的 Web 应用程序。