React 的核心原理主要围绕以下几个方面:
1. 虚拟DOM (Virtual DOM)
1 2 3 4 5 6 7 8 9 10 11 12 13
| 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); }
<ul> <li key="a">A</li> <li key="b">B</li> </ul>
|
Diff规则:
- 同级比较:只比较同一层的节点
- Key的重要性:帮助React识别元素的移动、添加、删除
- 类型不同则重建:元素类型改变,整个子树重建
3. Fiber架构(React 16+)
1 2 3 4 5 6 7 8 9 10
| 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
| setState(newState);
requestIdleCallback(() => { });
workLoop(deadline) { while (有工作 && 有空闲时间) { performUnitOfWork(currentFiber); } }
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; let workInProgressHook = null;
function useState(initialState) { const hook = { memoizedState: initialState, queue: [], next: null }; 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; this.persist(); }
|
7. 组件更新机制
类组件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class Component { setState(partialState, callback) { this.updater.enqueueSetState(this, partialState, callback); 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(() => { 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. 核心优势
- 声明式编程:描述UI应该是什么样子
- 组件化:高内聚、低耦合
- 一次学习,随处编写:React Native、React VR
- 强大的生态系统
理解这些原理有助于:
- 编写更高效的代码
- 更好的性能优化
- 避免常见错误
- 理解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
|