React入门教程:从安装到第一个应用(一个深夜DevOps的视角)
凌晨两点,窗外只有零星几盏路灯还亮着。我刚处理完一个后端服务的CI流水线告警,顺手泡了杯速溶咖啡——别笑,远程办公久了,连咖啡豆都懒得磨了。就在这时,钉钉弹出一条消息:“明天下午3点前,把那个运营用的临时数据看板搭出来”。发信人是我们那位永远在赶deadline的产品经理。
我盯着屏幕,内心OS:“又是临时看板?上次不是说好用Grafana吗?”
但转念一想:这需求其实挺简单,就是几个图表加个筛选器,要是用React写个轻量级前端,对接现成的后端API,两个小时就能搞定。问题是我自己平时主要搞自动化脚本、K8s配置和Rust写的CLI工具,正经写React页面……还真没几次。
于是,我翻出去年双11期间为了救火临时学的React笔记,决定重新走一遍从零到部署的全流程。顺便写下这篇教程——既是为了帮像我这样“半路出家”的运维/后端工程师快速上手React,也是给未来可能又要被产品经理抓壮丁的自己留个备忘录。
为什么选React?和其他框架比比看
说实话,在2024年这个“前端框架比头发还多”的时代,选择React并不是因为它是最好的,而是因为它最不容易踩雷。我们团队里前后端分离做得比较彻底,后端用Go+gRPC,前端则允许各项目组自由选型。结果你猜怎么着?Vue、Svelte、SolidJS 都有人试过,但最后线上事故最多、交接最痛苦的,反而是那些“小而美”的新框架。
下面是我整理的一个对比表(基于我们团队过去一年的真实项目经验):
| 框架 | 学习曲线 | 生态成熟度 | 社区支持 | 与后端集成难度 | 运营工具兼容性 |
|---|---|---|---|---|---|
| React | 中等 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | 低 | 高(埋点、AB测试插件丰富) |
| Vue 3 | 低 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | 低 | 中 |
| } | |||||
| Svelte | 低 | ⭐⭐ | ⭐⭐ | 中 | 低 |
| Angular | 高 | ⭐⭐⭐⭐ | ⭐⭐⭐ | 高 | 中 |
注:运营工具兼容性指的是能否方便地接入如神策、GrowingIO、Google Analytics 等第三方埋点系统——这点对运营同学特别重要。
我们之前有个活动页用了Svelte,结果运营同学要加个点击热力图,折腾半天找不到合适的SDK,最后还是我手动注入了一段原生JS才搞定。那一刻我发誓:以后只要涉及运营需求,优先考虑生态成熟的框架。
而React,背靠Meta(虽然现在叫Meta了),GitHub上star数常年霸榜,npm包数量碾压同行。更重要的是,几乎所有主流UI库(Ant Design、MUI、Chakra UI)都优先支持React。对我们这种“不想花时间造轮子”的工程师来说,简直是救命稻草。
安装环境:别被Node.js版本坑了
作为天天和Docker、Terraform打交道的DevOps,我最怕的就是“在我机器上能跑”。所以第一步,一定要用明确的Node.js版本。
# 推荐用fnm或nvm管理Node版本
curl -fsSL https://fnm.vercel.app/install | bash
fnm install 18.17.0
fnm use 18.17.0
为什么选18.17.0?因为这是我们公司前端项目的标准版本,LTS(长期支持),且兼容Vite(后面会讲)。别用最新版Node,尤其是20.x,某些老package会出现ERR_REQUIRE_ESM之类的玄学错误——上周五我就被这玩意儿卡了半小时,差点把键盘扔了。
接着,创建React项目。千万别用create-react-app了! 那玩意儿已经停止维护,打包慢得像蜗牛,而且Webpack配置改起来像解谜游戏。
npm create vite@latest my-dashboard -- --template react
cd my-dashboard
npm install
Vite是尤雨溪(Vue作者)搞的构建工具,启动速度飞快,HMR(热更新)几乎无感。对我们这种习惯了kubectl apply -f秒级生效的人来说,等待Webpack编译5秒都是煎熬。
写第一个组件:别一上来就搞复杂状态
很多教程一上来就教你用useState、useEffect,搞得新手以为React就是个状态管理器。其实对于简单的运营看板,纯展示型组件就够了。
比如我们要显示一个用户增长曲线,后端已经提供了/api/stats/daily-users接口,返回格式如下:
{
"data": [
{ "date": "2024-06-01", "count": 1200 },
{ "date": "2024-06-02", "count": 1350 },
// ...
]
}
那前端代码可以非常干净:
// components/UserChart.jsx
import { useEffect, useState } from 'react';
export default function UserChart() {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch('/api/stats/daily-users')
.then(res => res.json())
.then(result => {
setData(result.data);
setLoading(false);
})
.catch(err => {
console.error('Failed to load user stats:', err);
setLoading(false);
});
}, []);
if (loading) return <div>加载中...</div>;
return (
<div className="chart-container">
<h2>日活用户趋势</h2>
<ul>
{data.map(item => (
<li key={item.date}>
{item.date}: {item.count} 人
</li>
))}
</ul>
</div>
);
}
💡 调试技巧:在Chrome DevTools的Network面板里,直接右键复制cURL命令,粘贴到终端就能复现请求——这对排查后端接口问题超有用。
注意这里没有用Redux、Zustand这些状态管理库。能不用就不用! 我见过太多项目,明明只有三个页面,硬是引入了Redux Toolkit,结果90%的代码都在写action和reducer模板。产品经理看了都说“卷”。
样式怎么搞?Tailwind真香警告
以前我写CSS都是直接内联或者用SCSS,直到被设计师吐槽“间距不一致”、“颜色值乱七八糟”。后来团队统一引入了Tailwind CSS,从此告别样式焦虑。
Vite创建项目时加上--template react-ts(带TypeScript的),然后:
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
配置tailwind.config.js:
module.exports = {
content: ["./index.html", "./src/**/*.{js,jsx,ts,tsx}"],
theme: {
extend: {},
},
plugins: [],
}
然后在src/index.css里加两行:
@tailwind base;
@tailwind components;
@tailwind utilities;
现在你可以这样写组件:
<div className="p-4 bg-white rounded-lg shadow-md">
<h2 className="text-xl font-bold text-gray-800 mb-2">运营看板</h2>
<UserChart />
</div>
Tailwind的好处在于:
- 所有间距、颜色、字体大小都来自预设值,保证设计一致性
- 不用起class名(再也不用纠结叫
user-card还是profile-box) - 支持响应式(
md:p-6这种写法太爽了)
而且运营同学提需求时可以说“把这个按钮改成primary色”,你直接查Tailwind文档就知道是bg-blue-500,不用再去翻Figma或者问设计师。
和后端联调:别忘了CORS和代理
作为经常被后端甩锅的运维,我深知跨域问题有多坑。本地开发时,React默认跑在http://localhost:5173,而后端API在http://api.internal:8080,浏览器直接给你一个CORS error。
解决方案有两种:
- 后端加CORS头(理想情况,但往往要等后端排期)
- 前端配代理(立刻能用,适合救火)
Vite支持在vite.config.js里配置代理:
export default defineConfig({
server: {
proxy: {
'/api': {
target: 'http://api.internal:8080',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
}
}
}
})
这样,前端代码里写fetch('/api/stats/daily-users'),Vite开发服务器会自动转发到后端真实地址,完全绕过浏览器CORS限制。
上线时怎么办?一般我们会让Nginx做反向代理:
location /api/ {
proxy_pass http://backend-service:8080/;
}
这样生产环境也不用改前端代码。运维的快乐就是:一次配置,到处运行。
部署上线:从GitHub到CDN
写完代码只是开始,真正的挑战是如何让它在线上跑起来。我们团队的做法是:
- 代码推到GitHub私有仓库
- GitHub Actions 自动构建并上传到AWS S3
- CloudFront 做CDN加速
.github/workflows/deploy.yml 示例:
name: Deploy Dashboard
on:
push:
branches: [main]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 18.17.0
- run: npm ci
- run: npm run build # 生成dist目录
- uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- run: aws s3 sync ./dist s3://my-dashboard-bucket --delete
📌 注意:
npm run build会生成静态文件,React应用本质就是一个HTML+JS+CSS的集合,不需要Node.js运行时!这点很多后端同学搞不清楚,总想着要起个Express服务器。
上传到S3后,CloudFront自动缓存,全球访问速度飞起。而且S3+CloudFront的费用极低,一个月不到10块钱,比租一台最低配ECS还便宜——老板听了直呼内行。
性能与兼容性:别让用户等太久
虽然这是个内部运营看板,但也不能忽视性能。我用Lighthouse跑了一下,发现两个问题:
- 首屏加载慢(主要是Chart.js太大)
- 没有设置缓存头
解决方案:
- 按需引入图表库:别直接
import Chart from 'chart.js',而是用动态导入:const Chart = await import('chart.js/auto'); - 配置Cache-Control:在S3上传时加元数据:
aws s3 cp dist/ s3://bucket/ --cache-control "max-age=31536000" --recursive
至于浏览器兼容性?放心,React 18 默认输出现代JS语法,但Vite会自动polyfill必要部分。我们测试过Chrome、Firefox、Edge最新版,甚至Safari 15+都没问题。如果你们公司还在用IE……建议先换产品经理。
结语:React不是银弹,但够用就好
折腾到凌晨四点,看板终于上线了。产品经理回了个👍,运营同学说“筛选功能很顺手”,后端同事也没来找我茬——这就是最好的反馈。
作为DevOps,我其实并不想深入前端细节。但在这个全栈协作越来越紧密的时代,懂一点React,能让你在跨团队沟通时少说十句“这不归我管”。
React的哲学很简单:组件化、声明式、单向数据流。你不需要成为前端专家,只要掌握基础,就能快速交付可用的产品。剩下的时间,我还要回去继续研究我的Rust——听说有个新crate可以自动生成OpenAPI客户端,说不定下次就能用Rust写前端了(笑)。
最后送大家一句真理:“能跑就行,别过度设计。” ——尤其是在面对产品经理的临时需求时。
Happy coding,愿你的CI流水线永不红,你的merge request一次过。

评论 0