render
使用方法
1
| React.render(<App/>,document.getElementById('root'))
|
把<App/>挂载到root节点上
1 2 3 4 5 6 7 8 9 10 11 12 13
| export function render( element, container, callback, ) { return legacyRenderSubtreeIntoContainer( null, element, container, false, callback, ); }
|
调用了legacyRenderSubtreeIntoContainer函数
legacyRenderSubtreeIntoContainer
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
| function legacyRenderSubtreeIntoContainer( parentComponent: ?React$Component<any, any>, children: ReactNodeList, container: Container, forceHydrate: boolean, callback: ?Function, ) { let root: RootType = (container._reactRootContainer: any); let fiberRoot; if (!root) { root = container._reactRootContainer = legacyCreateRootFromDOMContainer( container, forceHydrate, ); fiberRoot = root._internalRoot; if (typeof callback === 'function') { const originalCallback = callback; callback = function() { const instance = getPublicRootInstance(fiberRoot); originalCallback.call(instance); }; } unbatchedUpdates(() => { updateContainer(children, fiberRoot, parentComponent, callback); }); } else { fiberRoot = root._internalRoot; if (typeof callback === 'function') { const originalCallback = callback; callback = function() { const instance = getPublicRootInstance(fiberRoot); originalCallback.call(instance); }; } updateContainer(children, fiberRoot, parentComponent, callback); } return getPublicRootInstance(fiberRoot); }
|
一阵追踪后从react-reconciler/src/ReactFiberReconciler调用了createContainer
再一阵追踪调用了从ReactFiberRoot.new.js调用了
createFiberRoot->
new FiberRootNode创建一个根fiber节点 ->
createHostRootFiber创建后续节点并放在root的current里->返回了一个fiber节点
updateContainer
然后我们来看看updateContainer做了什么,在ReactFiberReconciler.js中我们找到了这个方法
1 2 3 4 5 6 7 8
| const update = createUpdate(expirationTime, suspenseConfig); update.payload = {element};
enqueueUpdate(current, update);
scheduleWork(current, expirationTime);
|
Update的结构:
tag:更新类型,UpdateState、ReplaceState、ForceUpdate、CaptureUpdate
payload:状态变更函数或新状态本身
callback:回调,作用于 fiber.effectTag,并将 callback 作为 side-effects 回调
expirationTime:deadline 时间,未到该时间点,不予更新
suspenseConfig:suspense 配置
next:指向下一个 Update
priority:仅限于 dev 环境
updateQueue的结构:
baseState:先前的状态,作为 payload 函数的 prevState 参数
baseQueue:存储执行中的更新任务 Update 队列,尾节点存储形式
shared:以 pending 属性存储待执行的更新任务 Update 队列,尾节点存储形式
effects:side-effects 队列,commit 阶段执行
scheduleWork