跳转至

React

主要内容

本篇整理前端基础与 React 实践:HTML/CSS/JavaScript/TypeScript、ES6、异步编程、React 组件、state、props、Hooks、useEffect 闭包问题、React Router、Next.js、Tailwind、Axios、Mock.js 和前端项目实践。

参考文档

  • 前端三件套.md
  • HTML.mdCSS.mdJavaScript.md
  • ES6和ES Next.md异步编程.mdTS.md
  • React.mdNext.js.mdTailwind CSS.md
  • Axios.mdMock.js.md浏览器开发者工具.md

学习路线

HTML 语义
  -> CSS 布局
  -> JavaScript 交互
  -> ES6 / async-await
  -> TypeScript 类型
  -> React 组件和状态
  -> Hooks
  -> Router / Next.js
  -> 请求、样式、工程化

前端三件套

HTML 定义结构和语义;CSS 定义表现和布局;JavaScript 定义行为和交互。

HTML 重点不是背标签,而是理解语义和结构。CSS 重点是盒模型、Flex/Grid、响应式、层叠规则。JavaScript 重点是函数、对象、数组、作用域、闭包、Promise 和 async/await。

TypeScript

TypeScript 给 JavaScript 加类型。全栈项目里它尤其重要,因为前端组件 props、API response、表单数据都需要结构约束。

常用:

type User = {
  id: number;
  name: string;
};

async function getUser(id: number): Promise<User> {
  const res = await fetch(`/api/users/${id}`);
  return res.json();
}

React 核心模型

React 可以理解为:

UI = f(state, props)

组件接受 props,内部维护 state,返回 UI。数据变化后,React 负责协调 UI 更新。相比手写 DOM,React 让我更关注“状态是什么”,而不是“每个 DOM 节点怎么改”。

JSX/TSX

注意:

  • 标签必须闭合。
  • 组件名大写开头。
  • 返回多个元素时用 <>...</>
  • class 写成 className
  • 事件写成 onClickonChange

useState

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

不要直接修改 state。数组和对象要创建新值:

setTodos([...todos, todo]);
setUser({ ...user, name: 'Alice' });

依赖旧值时使用函数式更新:

setCount((prev) => prev + 1);

useEffect

useEffect 用来处理副作用,比如请求、定时器、订阅。

useEffect(() => {
  const timer = setInterval(() => {
    setCount((x) => x + 1);
  }, 1000);
  return () => clearInterval(timer);
}, []);

飞书 React 文档里对闭包讲得很重要:每次渲染都像生成一个快照,effect 捕获的是那次快照里的 state 和 props。所以依赖数组不能乱写,不要“欺骗 React”。

React Router 与 Next.js

React Router 显式配置路由:

<Routes>
  <Route path="/" element={<Home />} />
</Routes>

Next.js App Router 用文件系统路由:

src/app/page.tsx -> /
src/app/blog/page.tsx -> /blog
src/app/blog/[slug]/page.tsx -> /blog/:slug
src/app/api/post/route.ts -> /api/post

Next.js 还涉及服务端组件、Route Handler、Server Action、Prisma、Zod、tRPC 等,是 React 之后的工程化框架。

Tailwind

Tailwind 是原子化 CSS:

<div className="flex min-h-screen items-center justify-center bg-gray-100" />

优点是快,不用反复命名 class;缺点是类名会变长,团队要统一风格。复杂复用仍然要抽组件。

Axios 与请求封装

项目里不要到处散写请求,应该封装:

  • baseURL。
  • token。
  • 超时。
  • 错误处理。
  • 统一响应结构。
const api = axios.create({ baseURL: '/api' });

Mock.js

后端还没完成时,Mock 可以让前端先开发。重点是 mock 数据要贴近真实 API,否则后期对接会出现字段名、类型、分页结构不一致。

实践项目

做一个“内训笔记管理器”:列表、详情、新建、编辑、删除、搜索、标签筛选。先 mock 数据,再对接后端。

常见坑

  • useEffect 依赖少写。
  • state 直接修改。
  • 列表 key 用 index 导致状态错位。
  • 请求没有错误处理。
  • 前后端字段名不一致。
  • Next.js Server/Client Component 边界不清楚。

飞书思考题

飞书 React 相关文档没有集中列出独立“思考题”,但 Hooks 文档通过计时器例子要求理解闭包和依赖数组。我的总结是:React 函数组件每次渲染都会形成一个状态快照,effect 和回调捕获的是当次快照。如果依赖数组不完整,后续执行时可能读到旧值。正确做法是写全依赖,或用函数式 state update、useReducer、useCallback 等方式减少依赖。

知识卡片

受控组件

表单输入值由 React state 控制,称为受控组件。它让输入、校验、提交逻辑更统一。

key

列表 key 的意义是帮助 React 识别元素身份。用 index 做 key 在增删排序时容易导致状态错位。

Server Component

Next.js 的 Server Component 默认在服务端执行,适合数据读取和减少客户端 JS;Client Component 适合交互。

Tailwind 复用

Tailwind 不等于不抽象。重复 UI 应抽组件,重复样式可用组件封装,而不是复制长 class。