React整体架构
以下是 React 整体架构的核心原理深度解析,结合源码与设计思想:
一、架构分层设计
React 采用三层架构设计,每层职责清晰分离:
┌─────────────────────┐ ┌─────────────────────┐
│ 渲染层 (Renderer) │◄───┤ 调度层 (Scheduler) │
└─────────────────────┘ └─────────────────────┘
▲ ▲
│ │
▼ │
┌─────────────────────┐ │
│ 协调层 (Reconciler) │◄──────────────┘
└─────────────────────┘
1. 协调层 (Reconciler)
- 核心职责:对比新旧 Virtual DOM,生成副作用列表
- 关键技术:Fiber 架构、双缓存树、Diff 算法
- 源码位置:
react-reconciler
包
2. 调度层 (Scheduler)
- 核心职责:控制任务优先级与执行时机
- 关键技术:Lane 模型、时间切片、任务队列
- 源码位置:
scheduler
包
3. 渲染层 (Renderer)
- 核心职责:将协调结果渲染到目标平台
- 常见实现:ReactDOM、React Native、React Test Renderer
- 源码位置:
react-dom
、react-native
等包
二、Fiber 架构核心
Fiber 是 React 16+ 的核心数据结构,实现了可中断渲染:
// 简化的 Fiber 节点结构
const fiber = {
type: 'div', // 组件类型
stateNode: null, // 对应的 DOM 节点或组件实例
props: {}, // 传入的属性
pendingProps: {}, // 待处理的新属性
memoizedState: null, // 状态值
return: null, // 父 Fiber 节点
child: null, // 第一个子 Fiber 节点
sibling: null, // 下一个兄弟 Fiber 节点
alternate: null, // 双缓存树中的另一个 Fiber
effectTag: 0, // 副作用标记 (插入/更新/删除)
lane: 0, // 优先级标记
// ...
};
双缓存树机制
React 使用双缓存技术提升渲染效率:
- current 树:当前屏幕上显示的内容
- workInProgress 树:正在构建的新树
- 通过
alternate
属性连接两棵树的对应节点
三、渲染流程详解
1. 更新触发阶段
// 当调用 setState 或 useState 的更新函数时
function dispatchSetState(fiber, action) {
// 创建更新对象
const update = createUpdate();
// 将更新加入队列
enqueueUpdate(fiber, update);
// 请求调度
scheduleUpdateOnFiber(fiber);
}
2. 调度阶段
// scheduler 包核心逻辑
function scheduleCallback(priorityLevel, callback) {
// 创建任务
const newTask = {
id: taskIdCounter++,
callback,
priorityLevel,
expirationTime: calculateExpirationTime(priorityLevel)
};
// 将任务加入调度队列
pushTask(newTask);
// 请求浏览器空闲时段执行任务
requestHostCallback(flushWork);
}
3. 协调阶段(Reconciliation)
// react-reconciler 核心循环
function workLoopConcurrent() {
while (workInProgress !== null) {
if (shouldYield()) {
// 时间片用尽,暂停工作
return;
}
performUnitOfWork(workInProgress);
}
}
function performUnitOfWork(fiber) {
// 1. 执行组件 render 函数
const nextChildren = beginWork(fiber);
// 2. 处理子节点
if (nextChildren) {
workInProgress.child = reconcileChildren(fiber, nextChildren);
} else {
// 3. 完成当前节点,处理副作用
completeUnitOfWork(fiber);
}
}
4. 提交阶段(Commit)
function commitRoot(root) {
const finishedWork = root.current.alternate;
// 1. 执行 DOM 操作前的副作用 (如 beforeMutation)
commitBeforeMutationEffects();
// 2. 执行 DOM 操作 (插入/更新/删除)
commitMutationEffects();
// 3. 执行 DOM 操作后的副作用 (如 layout)
commitLayoutEffects();
// 4. 更新当前树
root.current = finishedWork;
}
四、状态管理机制
1. Fiber 节点的状态存储
// 简化的 useState 实现
function useState(initialState) {
const fiber = getCurrentFiber();
let hook;
// 首次渲染创建 hook
if (fiber.memoizedState === null) {
hook = {
memoizedState: initialState,
queue: { pending: null },
next: null
};
fiber.memoizedState = hook;
} else {
// 后续渲染获取已有 hook
hook = fiber.memoizedState;
}
// 处理更新队列
const queue = hook.queue;
if (queue.pending !== null) {
const firstUpdate = queue.pending.next;
let update = firstUpdate;
do {
const action = update.action;
hook.memoizedState = action(hook.memoizedState);
update = update.next;
} while (update !== null && update !== firstUpdate);
queue.pending = null;
}
// 返回当前状态和更新函数
const setState = (action) => {
const update = createUpdate();
update.action = action;
enqueueUpdate(queue, update);
scheduleUpdateOnFiber(fiber);
};
return [hook.memoizedState, setState];
}
2. 状态更新路径
用户交互/异步操作 → setState/useState → 创建更新对象 →
加入更新队列 → 请求调度 → 协调阶段处理更新 →
提交阶段应用变更 → 触发重新渲染
五、事件系统
React 实现了合成事件(SyntheticEvent)系统:
- 事件委托:所有事件绑定到根 DOM 节点
- 事件冒泡:模拟原生事件传播机制
- 跨平台兼容:统一处理不同浏览器的差异
// 简化的事件绑定逻辑
function listenToEvent(eventType, target) {
// 检查是否已绑定该事件类型
if (!listeningMarker.has(eventType)) {
// 创建事件插件
const pluginModule = getEventPluginModuleForEvent(eventType);
// 在根节点上绑定原生事件
target.addEventListener(
eventType,
createEventListenerWrapperWithPriority(eventType, pluginModule)
);
listeningMarker.add(eventType);
}
}
六、性能优化机制
1. Memoization 技术
// React.memo 源码简化
function memo(Component, compare) {
const type = {
$$typeof: REACT_MEMO_TYPE,
render: Component,
compare: compare === undefined ? shallowEqual : compare,
};
return type;
}
// 浅比较实现
function shallowEqual(objA, objB) {
if (Object.is(objA, objB)) {
return true;
}
if (
typeof objA !== 'object' ||
objA === null ||
typeof objB !== 'object' ||
objB === null
) {
return false;
}
const keysA = Object.keys(objA);
const keysB = Object.keys(objB);
if (keysA.length !== keysB.length) {
return false;
}
for (let i = 0; i < keysA.length; i++) {
if (
!Object.prototype.hasOwnProperty.call(objB, keysA[i]) ||
!Object.is(objA[keysA[i]], objB[keysA[i]])
) {
return false;
}
}
return true;
}
2. 懒加载与 Suspense
// React.lazy 源码简化
function lazy(ctor) {
let lazyType = {
$$typeof: REACT_LAZY_TYPE,
_ctor: ctor,
_status: -1, // -1 未加载, 0 加载中, 1 已加载
_result: null,
};
return lazyType;
}
// Suspense 边界处理
function SuspenseComponent(props) {
const { fallback, children } = props;
try {
// 尝试渲染子组件
return children;
} catch (error) {
if (isThenable(error)) {
// 遇到 Promise,显示 fallback
return fallback;
}
throw error;
}
}
七、未来发展方向
- 并发模式(Concurrent Mode):更精细的优先级控制
- 自动批处理(Automatic Batching):优化状态更新性能
- 选择性水合(Selective Hydration):服务端渲染的性能提升
- React Server Components:服务端渲染的新范式
理解 React 整体架构有助于编写高性能、可维护的应用,特别是在处理复杂状态管理和性能优化时。通过掌握架构原理,可以更深入地理解 React 的设计哲学,避免常见的性能陷阱。