用React写第一个应用:从零到部署的实战之路

清香如茶
2025-06-16 12:07
阅读 550

我第一次接触 React 是在三年前的一次团队项目中。当时的项目是一个内部使用的员工管理系统,前端采用的是 jQuery + 原生 JS 的方式来开发。随着需求越来越多,代码越来越臃肿,维护起来异常困难。为了改善开发效率和代码结构,我们决定尝试使用现代前端框架进行重构,最终选择了当时刚升级到 Hooks API 不久的 React。

这篇文章想分享一下我最初学习 React 的过程,特别是从安装到跑出第一个完整功能的小应用的经历。希望你能从中感受到学习一个新框架的真实过程——不是一蹴而就,而是一边踩坑一边成长。


初识React:为什么是它?

初识React:为什么是它?

刚开始听到“组件化”、“虚拟DOM”这些词时我也一头雾水。但真正动手之后,我发现 React 最大的吸引力在于它的“可组合性”和清晰的数据流。不像之前的 jQuery 那样到处操作 DOM,React 让我把注意力集中在数据的变化上,UI 自动更新,这对一个习惯了手动控制一切的人来说简直是一种解脱。

更重要的是,React 社区活跃、文档完善,很多主流 UI 框架比如 Ant Design、Material-UI 都有 React 版本支持,这对于快速搭建界面帮助很大。


第一个挑战:安装与环境搭建

第一个挑战:安装与环境搭建

还记得我第一个问题就是:“React 怎么装啊?”现在来看很简单,但在当时真的让人有点迷糊。

开始我想直接像引用 jQuery 一样通过 <script> 标签引入 React 和 ReactDOM,结果折腾了半天也没成功,还遇到了版本不一致的问题。后来才知道,现代 React 项目几乎都是基于构建工具(Webpack 或 Vite)和模块系统开发的。

最后我是用 create-react-app 来快速生成项目的,这也是 Facebook 官方推荐的方式:

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

这套工具链背后做了很多事情:配置了 Webpack、Babel、ESLint、Jest 等一系列工具,让我们可以专注于编码而不是配置。不过也是后来我才意识到,一旦你需要自定义构建流程,就得去“弹出”(eject)或者使用 Vite 等更灵活的工具。

小插曲:我有一次误删了 node_modules 又没 commit package.json,重新装的时候版本不一致导致项目跑不起来。从此以后我都习惯加 -S 参数把依赖明确保存下来。


实战项目:做一个待办事项列表(Todo List)

实战项目:做一个待办事项列表(Todo List)

为了练习 React 的基本概念,我决定做一个简单的 Todo List 应用。目标包括:

  • 添加任务
  • 删除任务
  • 切换任务完成状态
  • 本地存储记录

这个项目虽然简单,但已经足够覆盖 React 的基本能力了。

组件设计思路

React 强调“组件化”,所以我拆分了几个基础组件:

  • App:主入口组件,负责整体结构
  • TodoList:展示所有任务
  • TodoItem:单个任务项
  • TodoForm:添加任务的表单

这种结构让我第一次感受到组件复用的魅力。每个组件只关注自己那部分逻辑,大大降低了维护成本。


动手写代码:从 App 开始

动手写代码:从 App 开始

首先看下 App.js

import React, { useState } from 'react';
import TodoForm from './components/TodoForm';
import TodoList from './components/TodoList';

function App() {
  const [todos, setTodos] = useState([]);

  const addTodo = (text) => {
    const newTodos = [...todos, { text, completed: false }];
    setTodos(newTodos);
    saveToLocalStorage(newTodos);
  };

  const toggleComplete = (index) => {
    const newTodos = [...todos];
    newTodos[index].completed = !newTodos[index].completed;
    setTodos(newTodos);
    saveToLocalStorage(newTodos);
  };

  const deleteTodo = (index) => {
    const newTodos = todos.filter((_, i) => i !== index);
    setTodos(newTodos);
    saveToLocalStorage(newTodos);
  };

  const saveToLocalStorage = (todos) => {
    localStorage.setItem('todos', JSON.stringify(todos));
  };

  return (
    <div className="App">
      <h1>我的待办清单</h1>
      <TodoForm onAdd={addTodo} />
      <TodoList
        todos={todos}
        onToggle={toggleComplete}
        onDelete={deleteTodo}
      />
    </div>
  );
}

export default App;

这段代码使用了 React 16.8+ 的 useState Hook 来管理状态,替代了类组件中的 this.state。这对我这种初学者来说更容易理解和调试。


子组件:TodoForm

import React, { useState } from 'react';

function TodoForm({ onAdd }) {
  const [text, setText] = useState('');

  const handleSubmit = (e) => {
    e.preventDefault();
    if (!text.trim()) return;

    onAdd(text);
    setText('');
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        placeholder="新增一项任务..."
        value={text}
        onChange={(e) => setText(e.target.value)}
      />
      <button type="submit">添加</button>
    </form>
  );
}

export default TodoForm;

可以看到这里用了受控组件的方式处理表单输入,这是 React 推荐的做法,数据由 React 控制,避免了混乱的状态同步问题。


TodoList 与 TodoItem

function TodoList({ todos, onToggle, onDelete }) {
  return (
    <ul>
      {todos.map((todo, index) => (
        <TodoItem
          key={index}
          todo={todo}
          index={index}
          onToggle={onToggle}
          onDelete={onDelete}
        />
      ))}
    </ul>
  );
}

function TodoItem({ todo, index, onToggle, onDelete }) {
  return (
    <li style={{ textDecoration: todo.completed ? 'line-through' : '' }}>
      <span onClick={() => onToggle(index)}>{todo.text}</span>
      <button onClick={() => onDelete(index)}>删除</button>
    </li>
  );
}

这部分展示了 React 的声明式编程风格。我们不需要关心如何去操作 DOM,只需要描述 UI 应该是什么样的,React 会帮你高效地更新。


踩坑经验:那些让我抓狂又收获满满的日子

1. 状态更新不及时?

我一开始在 setTodos() 后立即取值发现数据没有更新,后来才知道 React 的状态更新可能是异步的。解决方案是使用 useEffect 监听变化:

useEffect(() => {
  console.log('当前 todos:', todos);
}, [todos]);

2. 列表 key 的陷阱

最开始我没给列表加 key,后来渲染顺序不对的时候才发现这个问题。key 最好使用唯一 ID,实在没有的话也至少要确保数组稳定不变。

3. 多层嵌套组件传参麻烦?

最开始我把事件层层传递,写得非常复杂。后来学会了用 Context 或 Redux 进行全局状态管理,再结合自定义 Hook 封装逻辑,代码清爽多了。

4. 样式混乱?

我原本用 CSS 全局样式,不小心被其他组件影响了。后来改用 CSS Modules,或者使用 styled-components 这类库,让样式模块化更容易维护。


性能优化与兼容性考虑

虽然只是个小项目,但也让我开始思考一些生产级问题。

  • 防抖处理搜索框输入:当用户快速输入时,频繁触发 API 请求会影响性能。这时候可以用 lodash 的 debounce。
  • 移动端适配:使用 rem / vh 单位做响应式布局,加上媒体查询处理不同设备。
  • 浏览器兼容性:Babel 默认不会编译到太低版本的浏览器,需要在 browserslist 里设置目标平台。
  • 首次加载慢? 可以做 code splitting + lazy loading,按需加载组件。

成果展示与后续演进

当我第一次看到那个能够添加、删除、打勾的小应用在我自己的电脑上跑起来的时候,心里确实挺激动的。虽然只是一个小小的 todo app,但它代表着我对 React 已经有了基本的理解和掌控。

后续我还尝试把数据存在后端接口,接入 axios 发起请求,并且加上了路由跳转(用了 react-router),甚至尝试用 Redux 替代掉局部 state,一步步向实际项目靠近。


给新手的几点建议

如果你现在正准备学 React,以下是我一路走来的一些心得:

  1. 别一上来就学全家桶:先掌握 React 核心思想(组件化、状态管理),再逐步了解生态。
  2. 多动手:看书/视频不如写一个小项目来得实在。todo list、天气预报、博客后台都可以。
  3. 别怕踩坑:报错不可怕,学会看错误信息是第一步,查官方文档是第二步。
  4. 工具很重要:熟练使用 Chrome DevTools、React Developer Tools、VSCode 插件等,能大幅提升调试效率。
  5. 持续跟进社区趋势:React 生态发展很快,比如现在的 Server Components、React Compiler、RSC 架构等都值得关注。

结语:从入门到实战,每一步都算数

React 并不是一个难学的框架,但真正理解它的哲学、写出可维护的大项目却需要时间和实践。我希望这篇从个人真实经历出发的文章,能让你少走点弯路。

如果你刚刚入门 React,不妨也从写一个 Todo List 开始吧。记住一句话:不要等你准备好才开始写,而是写着写着你就准备好了

加油!希望你也能从这份热爱中找到属于你的成就感 🚀

评论 0

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