docs: update tutorial

This commit is contained in:
cqh963852 committed 2026-08-19 13:23:30 +08:00
1 parent 654cb4e981
commit 1042c0536e
11 files changed
+9091 -12379

No files matched your search

@@ -0,0 +1,65 @@
---
sidebar_position: 2
---
# 数据流与数据副本
## 什么是数据流
数据流描述的是数据在系统中的流动方向:数据从哪里产生,经过哪些处理,最终流向哪里。
以一个典型的前端页面为例
```
用户操作(事件) -> 更新数据(state) -> 重新渲染(view) -> 用户看到新界面
```
单向数据流的好处是:数据的变更路径清晰,出问题时可以顺着方向排查。
## 系统行为与数据
系统的行为本质上是数据随时间的变化。界面只是数据在某一时刻的快照。
```ts
// 数据决定界面:list 是什么,页面就渲染什么
function render(list: TodoItem[]) {
// ...
}
```
理解了"界面是数据的投影",很多问题就变成了数据问题:界面不对,先检查数据对不对、数据什么时候被改了。
## 数据副本(数据孤岛)
当同一份数据被多个地方持有副本时,问题就出现了
- 修改了 A 副本,B 副本还是旧值,界面之间不一致
- 不知道哪份副本是"权威数据"(source of truth)
这就是所谓的数据孤岛:每份数据各自为政,互相不同步。
### 解决思路
1. **单一数据源**:同一份数据只在一个地方持有,其他地方通过引用或订阅获取
2. **不可变更新**:修改时返回新副本,而不是就地修改,让变更可追踪
```ts
// 多副本,各自为政(数据孤岛)
let listA = [1, 2, 3];
let listB = [1, 2, 3]; // 与 listA 无关联
// 单一数据源 + 派生
const list = [1, 2, 3];
const activeList = list.filter((item) => item !== 0); // 从 list 派生
```
在前端框架中的体现
- React 的 `state` 与 `props`:数据自上而下流动,子组件不直接修改
- 派生数据不单独存储,而是在渲染时计算
## 小结
- 界面是数据的投影,先保证数据正确
- 保持数据流单向、可追踪
- 避免同一份数据的多副本,维护单一数据源
@@ -0,0 +1,63 @@
---
sidebar_position: 1
---
# 纯函数与副作用
## 什么是纯函数
纯函数需要同时满足两个条件
1. 相同的输入,总是返回相同的输出
2. 执行过程中不产生任何副作用
```ts
// 纯函数:只依赖入参,不修改外部状态
function add(a: number, b: number): number {
return a + b;
}
```
```ts
let count = 0;
// 非纯函数:修改了外部变量,产生了副作用
function increase(): number {
count += 1;
return count;
}
```
## 什么是副作用
副作用是指函数在执行过程中,对外部环境产生了影响。常见的副作用包括
- 修改外部变量或对象属性
- 发起网络请求
- 操作 DOM
- 读写文件、数据库
- `console.log`
## 为什么要区分
纯函数具有可预测性:只要输入确定,输出就确定。这使得
- **易于测试**:不需要 mock 外部环境
- **易于缓存**:相同输入可以直接返回缓存结果
- **易于推理**:阅读代码时不需要追踪外部状态
在前端框架中,这个概念随处可见。React 的函数组件在渲染阶段就要求保持纯净,副作用被统一收拢到 `useEffect` 中,本质上就是把"计算"和"影响外部世界"这两件事分开。
## 实践建议
1. 尽量把视图渲染逻辑写成纯函数,输入输出清晰
2. 把副作用集中在边界处(入口、事件回调、`useEffect`)
3. 修改数据时,不直接改动原数据,而是返回新的副本。(或者依赖框架的修改能力)
```ts
// 直接修改原数组(副作用)
list.push(item);
// 返回新数组(无副作用)
const newList = [...list, item];
```