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. JSXReact.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. 流程总结

react 渲染流程