LESSON 4.4 / MODERN FRONTEND

React:用组件组织界面

React 用组件描述界面。组件接收数据并返回页面结构,页面会随着状态变化重新计算需要显示的内容。

预计阅读约 25 到 40 分钟
完成结果把任务页面拆成职责清楚的组件,并能沿组件树说明每项数据从哪里传入。
本课目标
  • 把任务页面拆成职责清楚的组件,并能沿组件树说明每项数据从哪里传入。
  • 原生 Web、框架和构建工具的关系
  • 检查React:用组件组织界面后,应当把任务页面拆成职责清楚的组件,并能沿组件树说明每项数据从哪里传入,并保留类型检查、生产构建、浏览器行为和请求结果作为可重复检查的依据。
开始之前
  • 完成 4.3「TypeScript:先把数据形状说清楚」
01

FOUNDATION

必须理解

React 用组件描述界面应该怎样随数据变化。它减少手动寻找和修改 DOM 的代码,让页面由可组合的函数与明确输入构成。

本课依次讲清原生 Web、框架和构建工具的关系、组件、JSX、props 与组合和按业务单元拆分,而不是拆得越细越好,最后通过“在页面组件组合三者,验证新增和完成操作”检查学习结果。

先建立整体直觉

组件像积木模具:TaskItem 定义一条任务长什么样,传入不同 props 就得到不同内容;多个 TaskItem 组合成列表,再组合成页面。

贯穿本课的实际场景

任务应用拆为 TaskForm、TaskList、TaskItem 和 FilterBar;页面组件保存任务数据并把需要的信息传给子组件。

概念 1

原生 Web、框架和构建工具的关系

先用白话理解

React 组件通常就是一个返回界面描述的 JavaScript 函数,名字要用大写开头。JSX 看起来像 HTML,其实是让你能在 JavaScript 里更直观地描述页面。

基础概念

原生 Web 平台提供 HTML、CSS、JavaScript 和浏览器 API;React 是用于声明用户界面的库;构建工具负责转换模块、JSX 与资源并提供开发体验。

进一步理解

React 不替代浏览器,最终仍生成浏览器能处理的 DOM。它主要改变组织界面和状态更新的方式:开发者描述某个数据状态下界面应是什么。

构建工具也不是 React 本身。简单 React 可以通过其他方式运行,但真实项目通常需要模块解析、TypeScript、开发服务器和生产优化。

放进实际场景

任务列表仍由 button、ul 等原生元素组成,React 负责根据任务数组组合它们,构建工具把 TSX 转换并打包给浏览器。

容易混淆的地方

“框架”常被宽泛使用,但准确理解职责更重要:React 管 UI 模型,Next.js 再补路由与服务端能力,构建器处理工程转换。

这一小节记住:先分清平台、界面库和构建环境,错误才不会全部归咎于 React。

概念 2

组件、JSX、props 与组合

先用白话理解

props 是父组件交给子组件的输入,子组件应该把它当成只读数据。用户点了什么,可以通过回调告诉父组件,由确实拥有数据的地方决定怎么改。

基础概念

组件是可组合的界面单元,通常用函数根据输入返回界面描述;JSX 是在 JavaScript 中描述元素树的语法;props 是父组件传入的只读数据。

进一步理解

组件名称用大写开头,让 React 区分自定义组件与原生标签。父组件通过 props 传值和回调,子组件读取它们来显示或通知事件,不应直接修改 props。

组合允许父组件把内容嵌入子组件,也允许同一组件使用不同数据重复渲染。组件每次计算应尽量保持纯粹,相同输入得到相同界面。

放进实际场景

TaskList 把每条任务作为 props 交给 TaskItem;TaskItem 显示标题和完成状态,并通过 onToggle 通知上层用户点击。

容易混淆的地方

props 与 state 不同:props 由外部传入,state 是组件需要记住并可更新的信息;两者都能影响渲染。

这一小节记住:组件通过 props 接收事实,通过组合形成页面,通过回调报告事件。

概念 3

按业务单元拆分,而不是拆得越细越好

先用白话理解

一张任务卡、一个任务列表、一个新增表单都算清楚的业务单元,适合做组件。但如果只是包了一层文字,又没有独立职责,就没必要单独建文件。

基础概念

组件边界应围绕独立职责、可重复结构或独立变化原因划分。拆分目标是降低理解成本,而不是让文件数量最大化。

进一步理解

一个组件最好能用一句话说明职责,并拥有清楚输入与输出。任务卡、筛选栏和新增表单往往有独立语义;只有一层样式包装的 span 通常不值得单独抽象。

过大的组件会混合数据、交互和多个页面区域;过小的组件则迫使读者频繁跳转。可以先写清楚,再在重复或变化边界出现时重构。

放进实际场景

新增任务表单自己管理未提交输入并通过 onCreate 交出标题;列表只负责展示和空状态,页面负责协调数据。

容易混淆的地方

视觉区域不必一一对应组件。两个看起来分开的块若始终共享同一职责,可能应留在一起;同一区域也可能包含多个业务单元。

这一小节记住:好的组件边界让数据方向和修改位置更容易预测。

一个有明确输入的组件
运行前先确认
  • 代码位于支持 TypeScript 与 JSX 的 React 项目中。
  • 父组件会传入 title、done 和 onToggle 三个有效属性。
type TaskItemProps = {
  title: string;
  done: boolean;
  onToggle: () => void;
};

export function TaskItem({ title, done, onToggle }: TaskItemProps) {
  return <button onClick={onToggle}>{done ? "已完成" : "待完成"}:{title}</button>;
}
这段代码在做什么

阅读React:用组件组织界面示例时,组件通过 props 得到数据和动作,不需要知道任务保存在数组、API 还是数据库。

  1. TaskItemProps 先声明组件允许接收的输入及函数形状。
  2. 函数参数解构 props,并根据 done 选择显示文本。
  3. 点击 button 时只调用 onToggle,把修改决定交还给确实拥有任务数据的上层。
你应该观察到

组件根据不同 title 与 done 显示对应文字;点击后会调用父组件提供的回调,组件自身不会偷偷保存另一份任务状态。

02

AI COLLABORATION

AI 如何参与

在React:用组件组织界面这一课,AI 负责根据真实材料解释原生 Web、框架和构建工具的关系并指出遗漏,学习者负责控制范围、执行修改和核对类型检查、生产构建、浏览器行为和请求结果。

推荐协作顺序

  1. 1

    先给 AI 一张页面草图或现有 HTML,让它只画组件树。

  2. 2

    逐个确认组件的 props 和事件,再实现最小的 TaskItem。

  3. 3

    最后让它沿着数据流解释一次新增和切换完成,检查状态是否放对位置。

可直接使用的 Prompt
这是当前页面结构和数据。请先给组件树,每个组件只写职责、props 和事件出口。确认后再逐个转换为 JSX。不要为每个标签建组件,也不要把所有逻辑留在根组件。
应该得到什么

清晰的组件树与单向数据流,TaskItem 只通过 props 显示任务并触发回调;React:用组件组织界面的人工验收必须回到真实页面、请求、终端、测试或数据结果,不能用 AI 的文字说明代替。

人工检查清单

  • 确认 props 类型清楚、列表 key 稳定,并且组件没有在渲染期间直接修改数据。
  • 要求 AI 为每个候选组件写出职责、props 和事件,再判断是否值得拆分。
  • 运行页面并用不同 props、空数据和点击事件验证组件,而不只检查默认截图。
03

COMMON TRAPS

常见误区

下面三类问题会让任务看似完成,却经不起刷新、错误输入或真实环境检查。先看现象,再找原因和修正方法。

误区 1

一个巨型组件包办全部

你会看到
状态、请求和标记混在数百行中
为什么发生
状态、请求和界面共用一个修改入口,小改动也要理解整份组件。
怎样纠正
按业务区域和变化原因拆分
误区 2

每个标签都做组件

你会看到
跳转文件次数比理解收益更多
为什么发生
只有复用或独立职责才能抵消跳转文件和传递参数带来的成本。
怎样纠正
保留简单且只用一次的局部标记
误区 3

子组件修改 props

你会看到
数据来源变得不可预测
为什么发生
props 的所有者在父组件,子组件直接改写会让数据来源和更新时间难以追踪。
怎样纠正
通过事件通知拥有状态的组件更新
04

HANDS-ON

动手任务

把任务页面拆成职责清楚的组件,并能沿组件树说明每项数据从哪里传入。

准备条件
  • 完成 4.3「TypeScript:先把数据形状说清楚」

跟着做

  1. 01

    创建 Task 类型,包含 id、title、done。

  2. 02

    实现只显示一条任务的 TaskItem。

  3. 03

    实现 TaskList,通过 map 渲染多个 TaskItem。

  4. 04

    实现 TaskForm,提交标题并通过回调上报。

  5. 05

    在页面组件组合三者,验证新增和完成操作。

完成标志

把任务页面拆成职责清楚的组件,并能沿组件树说明每项数据从哪里传入。

加餐挑战

增加空列表提示组件,并保证没有任务时仍能理解下一步操作。

离开本课前,自问四件事

  • React、原生 Web 和构建工具分别负责什么?
  • 组件、JSX、props 与 state 之间是什么关系?
  • TaskItem 的输入和输出事件应该有哪些?
  • 我会用哪些信号判断某段界面值得拆成组件?
完成本课了吗?

确认完成后,会同步更新学习中心的课程学习进度。