react中的入口函数的模式
legacy
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
| render() => legacyRenderSubtreeIntoContainer() => { legacyCreateRootFromDOMContainer() => { var shouldHydrate = forceHydrate || shouldXXXHeuristic(container); return createLegacyRoot(container, shouldHydrate? { hydrate: true } : undefined) => { return new ReactDOMBlockingRoot(container, LegacyRoot, options) => { this._internalRoot = createRootImpl(container, tag, options) => { var root = createContainer(container, tag, hydrate) => { return createFiberRoot(containerInfo, tag, hydrate) => { var root = new FiberRootNode(containerInfo, tag, hydrate) var uninitializedFiber = createHostRootFiber(tag) root.current = uninitializedFiber uninitializedFiber.stateNode = root initializeUpdateQueue(uninitializedFiber) return root } } return root } } }
} }
|
创建Update对象
对于HostRoot或者ClassComponent会使用initializeUpdateQueue创建updateQueue,然后将updateQueue挂载到fiber节点上
1 2 3 4 5 6 7 8 9 10 11 12
| function initializeUpdateQueue(fiber) { var queue = { baseState: fiber.memoizedState, firstBaseUpdate: null, lastBaseUpdate: null, shared: {pending: null}, effects: null } fiber.updateQueue = queue }
|
然后我们进入updateContainer
函数
updateContainer
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| function updateContainer(element, container, parentComponent, callback) {
var lane = requestUpdateLane
var update = createUpdate(eventTime, lane) update.payload = { element: element } enqueueUpdate(current, update) scheduleUpdateOnFiber(current, lane, eventTime) return lane; }
|
1 2 3 4 5 6 7 8 9 10 11 12
| function createUpdate(eventTime, lane) { var update = { eventTime: eventTime, lane: lane, tag: UpdateState, payload: null, callback: null, next: null }; return update; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
function enqueueUpdate(fiber, update) {
updateQueue = fiber.updateQueue;
sharedQueue = updateQueue.shared pending = sharedQueue.pending
if(pending === null) { update.next = update } else { update.next = pending.next pending.next = update }
sharedQueue.pending = update }
|
scheduleUpdateOnFiber
1 2 3 4 5 6
| function scheduleUpdateOnFiber(fiber, lane, eventTime) { if (lane === SyncLane) { performSyncWorkOnRoot(root) } }
|
concurrent
起点 createRoot
创建根节点
1 2 3 4 5 6
| function createRoot(container, options) => { return new ReactDOMRoot(container, options) => { this.internalRoot = createRootImpl(container, ConcurrentRoot, options) } }
|
ReactDOMRoot.prototype.render
1 2 3 4 5 6
| ReactDOMRoot.prototype.render = ReactDOMBlockingRoot.prototype.render = function (children) => { var root = this.internalRoot
updateContainer(children, root, null, null) }
|
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
| function scheduleUpdateOnFiber(fiber, lane, eventTime) { if (lane === SyncLane) { performSyncWorkOnRoot(root); } else { ensureRootIsScheduled(root, eventTime); } ensureRootIsScheduled(root, currentTme) => {
var nextLanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes);
if (nextLanes === NoLanes) { } if (newCallbackPrPriority === SyncLanePriority) { scheduleCallback(performSyncWorkOnRoot.bind(null, root)) } else if (newCallbackPrPriority === S yncBatchedLanePriority) { scheduleCallback(ImmediatePriority$1, performSyncWorkOnRoot.bind(null, root)) } else { var schedulerPriorityLevel = lanePriorityToSchedulerPriority(newCallbackPrPriority) scheduleCallback(schedulerPriorityLevel, performConcurrentWorkOnRoot.bind(null, root)) } } }
|
两种模式的不同点
- createRootImpl中传入的第二个参数不一样 一个是LegacyRoot一个是ConcurrentRoot
1 2 3 4 5 6 7
| create(container, tag, options)
export type RootTag = 0 | 1 | 2 export const LegactRoot = 0 export const BlockingRoot = 1 export const ConcurrentRoot = 2
|
- requestUpdateLane中获取的lane的优先级不同
- 在函数scheduleUpdateOnFiber中根据不同优先级进入不同分支,legacy模式进入performSyncWorkOnRoot,concurrent模式会异步调度performConcurrentWorkOnRoot