从零到第一个React应用:一个前端工程师的实战笔记

#周浩天
2025-06-15 18:17
阅读 780

引言

大家好,我是一个有着五年前端开发经验的开发者。这些年,我经历过jQuery时代的繁杂DOM操作,也赶上了Vue和React崛起的大潮。如今回头看去,React已经成为很多公司技术栈的标配,无论是大型企业系统,还是中后台平台,甚至是一些面向C端用户的轻量级产品,都能看到React的身影。

今天想和大家分享的是我刚入门前端框架时的真实经历——如何从0搭建第一个React应用。文章将结合我的实际项目经验,详细讲解安装配置、核心概念、代码实现以及我在实践中遇到的一些“坑”。如果你是刚开始学React的小白,或者想转行前端但不知从何下手,那这篇文章或许能帮上你一把。


背景:为什么选择React?

背景:为什么选择React?

五年前我接手了一个内部管理系统项目,客户希望我们尽快交付一个界面友好、交互流畅的Web系统。当时的团队还在用jQuery写业务逻辑,页面交互全靠on('click'),代码冗长难维护。而客户又明确提出未来要支持模块化升级和组件复用。于是,我们决定尝试引入React作为技术栈的基础。

当时我们也考虑过Vue,最后还是选择了React,主要基于以下几点:

  • 社区活跃度高:React有庞大的开源生态,出现问题容易找到解决方案。
  • 企业广泛采用:比如Netflix、Airbnb、Facebook自家项目都用了React。
  • 理念简洁:React不像Angular那样封装得太多,它更关注UI层本身,学习曲线相对平缓。
  • 支持服务端渲染(SSR)和多端统一:虽然一开始没用这些特性,但后续扩展性强。

就这样,我们踏上了React的征途。


第一步:创建你的第一个React应用

第一步:创建你的第一个React应用

用户交互流程图-2

React官方推荐使用 Create React App(简称 CRA)来初始化新项目,这对于新手来说非常友好,省去了手动配置Webpack、Babel等工具的麻烦。

我当时也是按照如下命令快速开搞:

npx create-react-app my-first-app
cd my-first-app
npm start

执行完后,本地服务就跑起来了,默认在 http://localhost:3000 开启了一个空白页,控制台也没有报错,看起来一切正常。

项目结构一览

进入项目目录你会看到这样的结构:

my-first-app/
├── node_modules/
├── public/
│   └── index.html
├── src/
│   ├── App.js
│   ├── index.js
│   └── ...
├── package.json
└── README.md

其中最核心的就是 src/index.jsApp.js,前者负责将React组件挂载到HTML容器中,后者是我们主要的组件文件。


编写第一个React组件

还记得第一次打开App.js时候的兴奋心情吗?我把原本的 <p>Hello World</p> 改成了一个带有状态的按钮组件,体验到了React的魅力。

下面这段代码就是我当时写的第一个组件,现在看回去还挺青涩的 😂:

import React, { useState } from 'react';

function CounterButton() {
  const [count, setCount] = useState(0);

  return (
    <button onClick={() => setCount(count + 1)}>
      点了我 {count} 次!
    </button>
  );
}

export default function App() {
  return (
    <div className="App">
      <header className="App-header">
        <CounterButton />
      </header>
    </div>
  );
}

别看简单,但这是个典型的函数组件使用方式,包含了状态管理(useState)、事件绑定以及组件嵌套的写法。

一点小插曲

不过,刚开始的时候我也踩了一个小坑:点击按钮没有反应。排查了很久才发现是自己把 setCount 写成 setCount(count),导致每次点击都只是设置相同的值,没有触发更新。这提醒我们,在函数组件里修改状态一定要注意传入的是新的值或通过函数式更新,例如:

setCount(prev => prev + 1);

这样可以避免闭包陷阱的问题。


项目实践中的真实挑战

真正让我对React有一个深刻理解的,是在一次迭代中我们要做一个用户信息展示+数据过滤+导出功能的列表页。我们遇到了一些比较典型的问题:

问题一:组件划分不清晰,代码臃肿

一开始我们直接在 App.js 中写了所有东西,包括筛选表单、表格、分页器和导出按钮。随着需求越来越多,这个文件变得越来越大,维护起来十分痛苦。

解决方案:

我们按照模块职责拆分出了几个子组件:

  • <UserSearchForm /> —— 负责筛选条件输入
  • <UserTable /> —— 展示用户数据表格
  • <Pagination /> —— 分页组件
  • <ExportButton /> —— 数据导出按钮

每个组件只关注自己的功能,并通过props传递必要的参数。最终整个App变得清爽多了。

问题二:多个组件共享数据状态

不同组件之间需要共享搜索关键词、分页信息和当前列表数据。

解决方案:

我们当时选择了React的状态管理方案中最基础的方式:状态提升

我们将筛选条件和分页等状态提升到父组件(也就是App),然后通过props向下传递给各个子组件。这种方式适用于中小型项目,简单直接,不需要引入Redux或其他复杂工具。

示例简化版代码:

function App() {
  const [keyword, setKeyword] = useState('');
  const [page, setPage] = useState(1);
  const [users, setUsers] = useState([]);

  // 模拟API请求
  useEffect(() => {
    fetch(`/api/users?keyword=${keyword}&page=${page}`)
      .then(res => res.json())
      .then(data => setUsers(data));
  }, [keyword, page]);

  return (
    <div>
      <UserSearchForm keyword={keyword} onSearch={setKeyword} />
      <UserTable users={users} />
      <Pagination currentPage={page} onChange={setPage} />
    </div>
  );
}

实战技巧与调试经验分享

在长期使用React的过程中,我发现一些开发习惯和技术选型能显著提升效率和可维护性。

使用ESLint + Prettier规范代码风格

项目初期我就引入了ESLint和Prettier来做代码格式检查和自动美化。特别是对于多人协作项目来说,统一代码风格很重要。

安装命令大致如下:

npm install eslint prettier eslint-config-prettier eslint-plugin-react eslint-plugin-jsx-a11y eslint-plugin-import --save-dev

再配合 .eslintrc.js.prettierrc 文件做个性化配置,就可以自动修复大部分低级错误。

Chrome DevTools插件 —— React Developer Tools

这个Chrome插件几乎是每个React开发者必备的调试工具。它不仅能查看组件树结构,还能实时查看props和state的变化,调试起来非常直观。

我记得有一次发现某个组件的数据始终不对,结果通过DevTools一看,发现props传的是字符串,但组件期望的是Number类型。这种问题肉眼很难看出,用插件一下就定位到了。

性能优化建议

React默认已经做了很好的性能优化,但在某些场景下还是要额外注意:

  1. 合理使用useMemo / useCallback
    对于依赖计算密集型的操作,使用 useMemo 避免重复计算;而对于频繁定义的函数,使用 useCallback 来防止不必要的重新渲染。

  2. 列表项Key的选取
    在遍历数组生成列表项时,key属性一定要唯一,且最好用稳定ID而不是index。比如数据库返回的主键,而不是数组索引。

  3. 避免在render里频繁调用函数
    曾经有同事为了图方便在JSX里面调用 formatDate() 函数,结果每次重新渲染都要调用上百次,影响性能。正确做法是提前处理好,或者使用memo化的函数。


踩过的坑与避雷指南

前端性能优化图表-1

下面是一些我在工作中遇到的真实问题,记录下来希望能帮助你也少走弯路。

1. useEffect依赖项没写全,导致闭包问题

这是一个经典误区。比如我们想在组件加载时获取用户数据:

useEffect(() => {
  fetch(`/api/user/${userId}`).then(...);
}, []);

但你会发现,即使userId变化了,fetch请求仍然使用的旧值。这是因为依赖项数组 [ ] 导致useEffect只执行一次,闭包中的userId始终不变。

正确的做法是把所有外部变量加入依赖项:

useEffect(() => {
  fetch(`/api/user/${userId}`).then(...);
}, [userId]);

或者使用函数式更新方式:

const [userId, setUserId] = useState();
useEffect(() => {
  const id = userId;
  fetch(`/api/user/${id}`).then(...);
}, [userId]);

2. 错误地在render中执行副作用

有时候我们会想在组件渲染的时候做一些副作用,比如埋点、打印日志。千万别直接在render函数里写,会导致副作用多次执行。

应该使用useEffect来包裹副作用逻辑:

useEffect(() => {
  console.log('Component rendered');
}, []);

并且记得指定依赖项为空数组,确保只在组件挂载时执行一次。

3. 忽略浏览器兼容性测试

虽然Create React App 已经帮你处理了大部分polyfill,但在IE11等老浏览器上还是会有问题。比如async/await语法、Promise对象、箭头函数等都会导致报错。

解决办法之一是在package.json中明确指定目标浏览器范围:

{
  "browserslist": [
    "> 0.5%",
    "last 2 versions",
    "not dead",
    "ie >= 11"
  ]
}

然后再检查编译后的输出是否包含所需的polyfill。


经验总结与建议

经过这几年的React开发,我总结了几条给新手的建议:

  1. 先掌握React核心概念,不要急着上手全家桶
    刚开始接触React,不需要一开始就引入Redux、TypeScript、MobX这些东西。先把组件、状态、生命周期、props这些弄清楚才是正事。

  2. 从真实业务出发写代码
    学习过程中尽量模拟真实业务场景,比如商品详情页、订单管理页等。不要光盯着计数器、待办事项这类玩具级例子。

  3. 保持代码整洁,善用模块化和组件化
    把每一个功能模块封装成独立组件,方便后期维护和复用。命名要见名知意,比如<LoginForm /><Component1 />要好得多。

  4. 多动手调试,多用浏览器开发者工具
    前端开发很注重实践,不要怕折腾。当你遇到问题时,第一步不是百度,而是试着用Chrome开发者工具分析网络请求、内存占用、组件结构等。

  5. 关注用户体验细节
    不只是功能对就行,要考虑加载状态、错误提示、空态展示、交互反馈等细节。比如点击按钮后加个loading动画,失败时弹个Toast提醒用户。


写在最后

回顾这几年,从一个React小白到现在能主导前端架构设计,离不开不断的实践和反思。React作为一个成熟的技术栈,确实值得投入时间和精力去掌握。希望这篇结合了真实项目经验和踩坑教训的文章,对你有所启发。

如果你刚刚入门React,不妨从创建一个简单的待办事项、计算器或天气查询页面开始。记住:代码写出来不怕丑,只要肯重构。坚持下去,你一定也能写出优雅、健壮的React应用!

💡 如果你有任何疑问,欢迎留言交流,我会尽可能一一回复 👋

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝