React 的核心原理主要围绕以下几个方面:

1. 虚拟DOM (Virtual DOM)

1
2
3
4
5
6
7
8
9
10
11
12
13
// 虚拟DOM是一个JavaScript对象
const virtualDOM = {
type: 'div',
props: {
className: 'container',
children: [
{
type: 'h1',
props: { children: 'Hello' }
}
]
}
}

工作原理:

  • React 创建虚拟DOM树(轻量级的JS对象)
  • 状态变化时,生成新的虚拟DOM树
  • 通过Diff算法比较新旧树的差异
  • 批量更新实际DOM(最小化操作)

2. Diffing算法(协调算法)

React 使用 O(n) 复杂度的启发式算法:

比较策略:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 不同类型元素 → 完全重建
if (old.type !== new.type) {
// 卸载旧组件,挂载新组件
}

// 相同类型元素 → 更新属性
if (old.type === new.type) {
// 只更新变化的属性
updateProperties(oldNode, newNode);
}

// 列表元素使用key优化
<ul>
<li key="a">A</li>
<li key="b">B</li>
</ul>

Diff规则:

  1. 同级比较:只比较同一层的节点
  2. Key的重要性:帮助React识别元素的移动、添加、删除
  3. 类型不同则重建:元素类型改变,整个子树重建

3. Fiber架构(React 16+)

1
2
3
4
5
6
7
8
9
10
// Fiber节点结构
const FiberNode = {
type: FunctionComponent | ClassComponent | HostComponent,
stateNode: Component实例 | DOM节点,
return: 父Fiber,
child: 第一个子Fiber,
sibling: 兄弟Fiber,
alternate: 上次渲染的Fiber,
effectTag: 需要执行的副作用(PLACEMENT, UPDATE, DELETION等)
}

Fiber核心概念:

  • 增量渲染:将渲染工作拆分成多个小任务
  • 可中断:React可以暂停、恢复渲染
  • 优先级调度:为不同类型的更新分配优先级

4. 渲染流程

初始化渲染:

1
2
3
4
1. JSX → React.createElement() → 虚拟DOM对象
2. 创建Fiber树(协调阶段)
3. 计算DOM更新(提交阶段)
4. 实际DOM操作

更新过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 1. 触发更新
setState(newState);

// 2. 调度更新(Scheduler)
requestIdleCallback(() => {
// 在空闲时间执行
});

// 3. 协调阶段(可中断)
workLoop(deadline) {
while (有工作 && 有空闲时间) {
performUnitOfWork(currentFiber);
}
}

// 4. 提交阶段(不可中断)
commitRoot();

5. Hooks原理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
let hookIndex = 0;  // 当前hook索引
let workInProgressHook = null; // 当前处理的hook

function useState(initialState) {
// 获取当前hook
const hook = {
memoizedState: initialState,
queue: [], // 更新队列
next: null // 下一个hook
};

// 返回[状态, 更新函数]
return [hook.memoizedState, dispatchAction];
}

function dispatchAction(queue, action) {
// 创建更新对象
const update = { action, next: null };

// 将更新加入队列
// 调度重新渲染
scheduleUpdate();
}

Hooks规则:

  • 只能在函数组件顶层调用
  • Hook调用顺序必须稳定(基于链表实现)
  • 每个Hook有独立的内存单元

6. 事件系统

React使用合成事件(SyntheticEvent):

1
2
3
4
5
6
7
8
9
10
11
12
// 事件委托
document.addEventListener('click', dispatchEvent);

// 合成事件池
function SyntheticEvent(nativeEvent) {
this.nativeEvent = nativeEvent;
this.currentTarget = null;
// ... 其他属性

// 自动回收(React 17前)
this.persist(); // 阻止自动回收
}

7. 组件更新机制

类组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Component {
setState(partialState, callback) {
// 1. 将更新加入队列
this.updater.enqueueSetState(this, partialState, callback);

// 2. 调度更新
scheduleUpdate();
}

// 生命周期
shouldComponentUpdate(nextProps, nextState) {
// 决定是否更新
return true;
}
}

函数组件:

1
2
3
4
5
6
7
8
9
10
11
12
function MyComponent(props) {
// 每次渲染都会调用整个函数
const [state, setState] = useState();

// useEffect处理副作用
useEffect(() => {
// 副作用代码
return () => {
// 清理函数
};
}, [dependencies]);
}

8. 性能优化原理

React.memo:

1
2
3
4
5
6
7
const MemoComponent = React.memo(
MyComponent,
(prevProps, nextProps) => {
// 自定义比较逻辑
return prevProps.id === nextProps.id;
}
);

useMemo/useCallback:

1
2
3
4
5
6
7
8
9
10
11
const memoizedValue = useMemo(
() => computeExpensiveValue(a, b),
[a, b] // 依赖数组
);

const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b]
);

9. 新的并发特性(React 18+)

Concurrent Mode:

1
2
3
4
5
6
7
8
9
10
// 可中断的渲染
const root = ReactDOM.createRoot(container);

// 过渡更新(低优先级)
startTransition(() => {
setState(newState); // 不紧急的更新
});

// 延迟值
const deferredValue = useDeferredValue(value);

10. 核心优势

  1. 声明式编程:描述UI应该是什么样子
  2. 组件化:高内聚、低耦合
  3. 一次学习,随处编写:React Native、React VR
  4. 强大的生态系统

理解这些原理有助于:

  • 编写更高效的代码
  • 更好的性能优化
  • 避免常见错误
  • 理解React生态系统中的其他库

11. 流程总结

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
┌───────────────────────────────────────────────────────────────────────────────┐
│ React Fiber 完整更新流程 │
└───────────────────────────────────────────────────────────────────────────────┘

│
▼
┌─────────────────────┐
│ 触发更新 │
│ setState/useState等 │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ 创建 Update │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ Update 入队 │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ Scheduler │
│ 调度更新 │
└──────────┬──────────┘
│
▼
╔═══════════════════════════════════════════════════════════════════════════════╗
║ Render Phase(可中断) ║
║ ║
║ ┌──────────────┐ ║
║ │ workLoop │ ║
║ └──────┬───────┘ ║
║ │ ║
║ ▼ ║
║ ┌────────────────────┐ ║
║ │ performUnitOfWork │ ║
║ └─────────┬──────────┘ ║
║ │ ║
║ ▼ ║
║ ┌────────────────────┐ ║
║ │ beginWork │ ║
║ │ 协调当前 Fiber │ ║
║ └─────────┬──────────┘ ║
║ │ ║
║ ▼ ║
║ ┌───────────────┐ ║
║ │ 处理组件/Hook │ ║
║ └───────┬───────┘ ║
║ │ ║
║ ▼ ║
║ ┌───────────────┐ ║
║ │ 有子节点? │ ║
║ └───────┬───────┘ ║
║ YES │ │ NO ║
║ │ └──────────────────────┐ ║
║ ▼ ▼ ║
║ 继续向下遍历 completeUnitOfWork ║
║ │ ║
║ ▼ ║
║ ┌─────────────┐ ║
║ │ completeWork│ ║
║ └──────┬──────┘ ║
║ │ ║
║ ▼ ║
║ 收集副作用/Effect ║
║ │ ║
║ ▼ ║
║ 向上回溯 Fiber ║
║ │ ║
║ ▼ ║
║ 完成新的 Fiber Tree ║
║ ║
║ ★ Render 阶段主要做: ║
║ Reconciliation / Diff / 计算出“应该怎么变” ║
║ 不直接修改真实 DOM ║
║ 可以被 Scheduler 中断、暂停、恢复 ║
╚═══════════════════════════════════════╤═══════════════════════════════════════╝
│
▼
┌─────────────────────┐
│ commitRoot │
└──────────┬──────────┘
│
▼
╔═══════════════════════════════════════════════════════════════════════════════╗
║ Commit Phase(不可中断) ║
║ ║
║ ┌─────────────────────┐ ║
║ │ Before Mutation │ ║
║ │ 变更之前 │ ║
║ └──────────┬──────────┘ ║
║ │ ║
║ ├────► getSnapshotBeforeUpdate ║
║ │ ║
║ ▼ ║
║ ┌─────────────────────┐ ║
║ │ Mutation │ ║
║ │ 变更阶段 │ ║
║ └──────────┬──────────┘ ║
║ │ ║
║ ▼ ║
║ 修改真实 DOM ║
║ 插入 / 更新 / 删除 DOM ║
║ │ ║
║ ▼ ║
║ ┌─────────────────────┐ ║
║ │ Layout │ ║
║ │ 布局阶段 │ ║
║ └──────────┬──────────┘ ║
║ │ ║
║ ├────► componentDidMount / componentDidUpdate ║
║ │ ║
║ └────► useLayoutEffect ║
║ ║
║ ★ Commit 阶段主要做: ║
║ 把 Render 阶段计算出来的结果真正提交到 DOM ║
║ 这一阶段不能像 Render 那样随意中断 ║
╚═══════════════════════════════════════╤═══════════════════════════════════════╝
│
▼
┌─────────────────────┐
│ 浏览器绘制 │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ Passive Effects │
│ useEffect │
└─────────────────────┘


━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
辅助分支
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

① Hooks 更新
───────────────────────────────────────────────────────────────────────────────

useState / useReducer / setState
│
▼
创建 Update
│
▼
Update 入队
│
▼
Scheduler
│
▼
Render Phase
│
▼
Commit Phase


② 并发渲染
───────────────────────────────────────────────────────────────────────────────

Render Phase
│
▼
是否出现更高优先级任务?
│
┌───┴────┐
│ │
否 是
│ │
▼ ▼
继续 中断当前 Render
│
▼
处理高优先级任务
│
▼
恢复原来的 Render
│
▼
继续工作


③ Suspense
───────────────────────────────────────────────────────────────────────────────

组件开始 Render
│
▼
等待数据/资源
│
▼
暂时无法完成
│
▼
显示 fallback
│
▼
数据准备完成
│
▼
重新 Render
│
▼
显示真实内容


④ Error Boundary
───────────────────────────────────────────────────────────────────────────────

Render / 生命周期发生错误
│
▼
Error Boundary
│
▼
捕获错误/更新状态
│
▼
显示 Fallback
│
▼
重新 Render