从零跑通React:一个创业狗的深夜实战手记
上周五凌晨两点,我刚刷完LeetCode第138题,正准备合上电脑去泡面,突然收到产品发来的微信:“老板说下周要上线新功能,前端用React重写,你不是一直说想学吗?”——得,这下不用跳槽了,直接在公司内部“转岗”了。
作为一家三十人不到的创业公司唯一全栈,我白天写Java后端、配Nginx、改测试脚本,晚上还得背面试题、研究LangChain。但说实话,React早就该学了。最近投的几家大厂,前端岗JD里清一色写着“熟练掌握React”,连后端岗都开始问虚拟DOM原理。不学不行,简历过不了筛。
所以,趁着这个“被迫营业”的机会,我决定从最基础的环境搭建开始,彻底搞懂React。这篇文章,就是我踩坑、填坑、再踩坑后的完整记录,希望能帮到和我一样被推上战场的兄弟。
为什么是React?别被“框架焦虑”绑架
先说清楚,我不是React脑残粉。Vue我也用过,Svelte看起来更酷,但现实是:GitHub上React的star数超200万,生态碾压级优势。更重要的是,求职市场认它。打开BOSS直聘,搜“前端开发”,90%的职位要求里有React。就连我们公司这次选型,也是因为“招人容易”。
但别被“框架战争”带节奏。对我这种边工作边刷题的打工人来说,能快速产出、能过面试、能跑线上,才是王道。React的组件化思想、Hooks API、丰富的社区资源,确实适合快速迭代——尤其适合我们这种产品经理天天改需求的团队。
安装:别信网上那些过时教程
很多老教程还在教create-react-app(CRA),但2024年了,Vite才是真香选择。CRA启动慢、配置黑盒、打包体积大,我们双11期间就因为CRA构建卡住,差点没上线。Vite基于ESM,冷启动快如闪电,HMR(热更新)几乎无感。
安装命令一行搞定:
npm create vite@latest my-react-app -- --template react
cd my-react-app
npm install
npm run dev
打开http://localhost:5173,看到那个旋转的React Logo,你就成功了。别小看这一步,上周我同事用Node.js 14跑,直接报错Unknown file extension ".ts",升级到Node 18才解决。记住:Node版本至少16+,推荐18 LTS。
写第一个组件:别只写Hello World
大多数教程到这儿就结束了,但真实项目哪有这么简单?我直接上一个带状态管理 + 用户交互 + 表单验证的小功能:一个待办事项(Todo)列表。
// src/App.jsx
import { useState } from 'react';
function App() {
const [todos, setTodos] = useState([]);
const [inputValue, setInputValue] = useState('');
const handleAddTodo = () => {
if (inputValue.trim() === '') return;
setTodos([...todos, { id: Date.now(), text: inputValue, completed: false }]);
setInputValue(''); // 清空输入框
};
const toggleTodo = (id) => {
setTodos(todos.map(todo =>
todo.id === id ? { ...todo, completed: !todo.completed } : todo
));
};
return (
<div className="app">
<h1>我的待办清单</h1>
<div>
<input
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
placeholder="输入任务..."
onKeyPress={(e) => e.key === 'Enter' && handleAddTodo()}
/>
<button onClick={handleAddTodo}>添加</button>
</div>
<ul>
{todos.map(todo => (
<li
key={todo.id}
style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}
onClick={() => toggleTodo(todo.id)}
>
{todo.text}
</li>
))}
</ul>
</div>
);
}
export default App;
这段代码虽然简单,但包含了React核心概念:
- useState:管理组件状态
- 事件处理:
onClick、onChange - 条件渲染:通过
style动态切换样式 - 列表渲染:
map生成元素,记得加key
特别注意:不要直接修改state!比如todos[0].completed = true是错的。必须用setTodos返回新数组,这是React响应式更新的基础。我第一次写的时候就犯这错,页面死活不更新,调试半小时才发现。
调试技巧:别只会console.log
创业公司没时间慢慢debug。我常用的组合拳:
- React DevTools:浏览器插件,直接看组件树、props、state
- useEffect依赖检查:开启严格模式(Strict Mode),会警告缺失依赖
- 错误边界:虽然小项目用不上,但面试常问
另外,控制台输出要带上下文。比如:
console.log('[App] todos updated:', todos);
比单纯console.log(todos)有用十倍,尤其当你有多个组件同时打印时。
构建与部署:别等上线才想起来
本地跑得好好的,一构建就报错?常见坑点:
- 路径问题:Vite默认
base: '/',如果部署在子目录,需在vite.config.js中设置 - 环境变量:
.env文件要以VITE_开头,否则会被过滤 - 静态资源引用:图片要用
import,别直接写相对路径
构建命令:
npm run build
生成的dist目录,丢给Nginx或GitHub Pages就行。我们公司用GitHub Pages做demo站,一行命令部署:
gh-pages -d dist
(记得先npm install -g gh-pages)
面试题关联:别学完就忘
学React不只是为了写代码,更是为了过面试。上面这个小例子,其实覆盖了高频面试题:
| 面试题 | 对应知识点 |
|---|---|
| React如何更新UI? | setState触发re-render,Diff算法对比虚拟DOM |
| 为什么列表要加key? | 帮助React识别哪些元素 changed/added/removed |
| useState和useEffect的区别? | useState存状态,useEffect处理副作用(如请求、订阅) |
| 如何优化性能? | React.memo、useCallback、useMemo避免不必要渲染 |
建议每学一个特性,就自问:“这能出什么面试题?” 比如学完useEffect,立刻想到“useEffect和useLayoutEffect区别?”——答案是前者异步执行(不阻塞渲染),后者同步执行(用于测量布局)。
总结:技术是手段,不是目的
折腾完这个小应用,已经是凌晨四点。虽然只是个Todo List,但它让我真正理解了React的“声明式”思维——你描述UI应该是什么样,而不是一步步操作DOM。这种范式转换,对后端出身的我来说,一开始很别扭,但现在觉得真香。
更重要的是,这个项目能放进GitHub仓库。哪怕只有100行代码,也比简历上写“熟悉React”有力得多。我打算把代码整理好,加个README,再录个GIF演示,直接当作品集用。
最后说句掏心窝的:创业公司没人教你,跳槽又卷得要死,唯一的出路就是边干边学,用产出倒逼输入。今天你搭的这个React应用,可能就是明天面试时的谈资,甚至是offer的敲门砖。
所以,别等“准备好”再开始。打开终端,敲下npm create vite,你的React之旅,现在就开始。
(完)
作者:一个在创业公司写全栈、深夜刷题、梦想进大厂的普通程序员。
GitHub:欢迎Star我的react-todo-demo(示例链接,实际请替换)
最近在学AI,如果你也对LangChain+React结合感兴趣,评论区留言,下期聊聊!

评论 0