docs: update tutorial
This commit is contained in:
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];
|
||||
```
|
||||
@@ -9,7 +9,7 @@ sidebar_position: 2
|
||||
1. 已创建react ts工程
|
||||
|
||||
>**提示**
|
||||
若未创建react ts工程,可以参考[使用vite创建react ts工程](https://github.com/idealjs/stack/blob/main/packages/stack-idealjs/docs/react/react_ts.md)文档
|
||||
若未创建react ts工程,可以参考[使用vite创建react ts工程](/docs/full_guide/react/react_ts)文档
|
||||
|
||||
## 项目初始化
|
||||
打开react ts工程
|
||||
|
||||
@@ -31,3 +31,64 @@ npm install
|
||||
```
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## 按步引入react包
|
||||
|
||||
除了直接用脚手架创建react工程,也可以在一个已有的vanilla工程中,按步引入react包。这个过程可以帮助理解react工程的最小组成。
|
||||
|
||||
### 1. 安装依赖
|
||||
|
||||
在vanilla工程目录下,运行以下命令
|
||||
|
||||
```
|
||||
npm install react react-dom
|
||||
npm install -D @types/react @types/react-dom @vitejs/plugin-react
|
||||
```
|
||||
|
||||
### 2. 配置vite
|
||||
|
||||
修改`vite.config.ts`,添加react插件
|
||||
|
||||
```ts
|
||||
import { defineConfig } from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
})
|
||||
```
|
||||
|
||||
### 3. 修改入口文件
|
||||
|
||||
把`index.html`中的入口指向react组件文件
|
||||
|
||||
```html
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
```
|
||||
|
||||
编写`src/main.tsx`
|
||||
|
||||
```tsx
|
||||
import React from 'react'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
|
||||
function App() {
|
||||
return <h1>Hello React</h1>
|
||||
}
|
||||
|
||||
createRoot(document.getElementById('app')!).render(<App />)
|
||||
```
|
||||
|
||||
同时在`index.html`的`body`中添加挂载点
|
||||
|
||||
```html
|
||||
<div id="app"></div>
|
||||
```
|
||||
|
||||
### 4. 运行项目
|
||||
|
||||
```
|
||||
npm run dev
|
||||
```
|
||||
|
||||
看到页面输出`Hello React`,说明react已经成功引入。
|
||||
@@ -8,7 +8,7 @@ vite 是一个现代化的前端构建工具,旨在提供快速的开发体验
|
||||
## 什么是vite
|
||||
访问网站 https://vitejs.cn/vite3-cn/guide/
|
||||
|
||||
## 创建vanilla ts工程
|
||||
## 创建 vanilla ts 工程
|
||||
### 打开终端
|
||||
使用快捷键`Ctrl+ ~` 打开终端
|
||||
|
||||
@@ -17,7 +17,15 @@ vite 是一个现代化的前端构建工具,旨在提供快速的开发体验
|
||||
```
|
||||
npm create vite@latest
|
||||
```
|
||||
2. 根据提示,输入名字并选择vanilla,再选择typescript
|
||||
2. 根据提示,输入名字并选择 vanilla,再选择 typescript
|
||||
|
||||
也可以直接指定模板,跳过交互。创建vanilla-ts工程
|
||||
|
||||
创建vanilla-ts工程
|
||||
|
||||
```
|
||||
npm create vite@latest vanilla-ts-test -- --template vanilla-ts
|
||||
```
|
||||
|
||||
3. 输入以下命令,进入项目
|
||||
```
|
||||
|
||||
@@ -7,7 +7,7 @@ sidebar_position: 1
|
||||
1. 已创建vanilla ts工程
|
||||
|
||||
>**提示**
|
||||
若未安装vanilla ts工程,可以参考[vite的入门](https://github.com/idealjs/stack/blob/main/packages/stack-idealjs/docs/vite/vite.md)文档
|
||||
若未安装vanilla ts工程,可以参考[vite的入门](/docs/full_guide/vite/)文档
|
||||
|
||||
## 项目初始化
|
||||
打开vanilla ts工程
|
||||
|
||||
@@ -10,23 +10,10 @@ sidebar_position: 1
|
||||
|
||||
软件工程更多讲究实践,而不是理论,所以希望读者能够实践多于阅读,如果某些章节实践过,可以直接跳过去。
|
||||
|
||||
我希望可以通过十几篇文章,让任何有兴趣的人入门前端工程师这个职业。
|
||||
我希望可以通过十几篇文章,让任何有兴趣的人入门全栈工程师这个职业。
|
||||
|
||||
## 路线图
|
||||
|
||||
文章方面,希望一天可以产出一篇文章,通过两个星期。让入门变成简单的事情。
|
||||
|
||||
网站建设方面,准备采用 docusaurus 框架,架设一个文档网站。
|
||||
|
||||
需要更新的部分
|
||||
|
||||
1. 创建 vite vanilla-js 工程。
|
||||
- 单独链接到快速创建命令篇。
|
||||
2. 按步引入 react 包。
|
||||
3. 快速创建命令,与执行效果。
|
||||
4. 工具篇,添加 vscode git graph 插件的介绍
|
||||
5. 高级篇
|
||||
1. 纯函数、副作用。
|
||||
2. 数据流,系统行为,数据副本(数据孤岛)。
|
||||
|
||||
6. 快速开始 -> 简单服务 补充 npx 命令相关。链接到工具篇
|
||||
@@ -13,7 +13,7 @@ sidebar_position: 1
|
||||
5. 确认已启动数据库
|
||||
|
||||
>**提示**
|
||||
如果不知道怎么启动数据库,可以参考使用 [Docker启动数据库](https://github.com/idealjs/stack/blob/main/packages/stack-idealjs/docs/docker/start.md)文档
|
||||
如果不知道怎么启动数据库,可以参考使用 [Docker启动数据库](/docs/recipes/docker/start)文档
|
||||
|
||||
## 项目初始化
|
||||
- 打开Next.js项目
|
||||
|
||||
@@ -95,3 +95,25 @@ git commit -m "test"
|
||||
```
|
||||
git push
|
||||
```
|
||||
|
||||
## vscode插件:Git Graph
|
||||
|
||||
命令行适合执行 git 操作,但查看提交历史、分支结构时,图形化工具更直观。
|
||||
|
||||
推荐在 vscode 中安装 **Git Graph** 插件。
|
||||
|
||||
### 安装
|
||||
|
||||
1. 打开vscode,进入扩展面板(快捷键`Ctrl + Shift + X`)
|
||||
2. 搜索`Git Graph`
|
||||
3. 点击安装
|
||||
|
||||
### 使用
|
||||
|
||||
安装后,在资源管理器中右键 git 仓库,选择`Git Graph: View Git Graph`,即可看到图形化的提交历史。
|
||||
|
||||
主要功能
|
||||
|
||||
- 查看分支、合并记录的可视化图谱
|
||||
- 查看每次提交的变更文件与代码差异
|
||||
- 直接在界面上执行 checkout、merge、rebase、创建分支等操作
|
||||
@@ -15,3 +15,9 @@ npx http-server
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 关于npx
|
||||
|
||||
`npx` 用于执行 npm 包中的可执行文件,不需要全局安装就可以运行一个包。
|
||||
|
||||
这里执行 `npx http-server`,npx 会临时下载 `http-server` 包并启动一个静态资源服务器,把当前目录作为网站根目录。
|
||||
Reference in new issue
Block a user