还处于初级学习阶段,懵懵懂懂,边学习边将自己的理解记录下来,后期随着理解的深入会不断回过头来完善。
ReactDOM.render
ReactDOM.render是渲染组件的第一步,接收三个参数:第一个是createElement创建出来的ReactElement,第二个是dom容器,用来存放ReactElement,第三个是回调函数,用于组件装载后执行的操作。
这个函数做的事情:它会调legacyRenderSubtreeIntoContainer,并将所有参数传给这个函数。然后后面的关键性操作就可以去legacyRenderSubtreeIntoContainer这里面看了。
render(
element: React$Element<any>,
container: DOMContainer,
callback: ?Function,
) {
return legacyRenderSubtreeIntoContainer(
null,
element,
container,
false,
callback,
);
}legacyRenderSubtreeIntoContainer
这个函数做的事情:
看container里有没有_reactRootContainer,我们这里先分析初次进来的情况,初次进来肯定是没有的,所以会去执行legacyCreateRootFromDOMContainer,legacyCreateRootFromDOMContainer里还会调用别的函数,兜兜转转返回一个FiberRoot。
再往下看,parentComponent传进来的就是null,所以直接执行root.render,即ReactRoot.render这个方法。
function legacyRenderSubtreeIntoContainer(
parentComponent: ?React$Component<any, any>,
children: ReactNodeList,
container: DOMContainer,
forceHydrate: boolean,
callback: ?Function,
) {
let root: Root = (container._reactRootContainer: any);
if (!root) {
// Initial mount
root = container._reactRootContainer = legacyCreateRootFromDOMContainer( // 返回一个FiberRoot
container,
forceHydrate,
);
// Initial mount should not be batched.这里还不懂,后面会学到
unbatchedUpdates(() => {
if (parentComponent != null) {
root.legacy_renderSubtreeIntoContainer(
parentComponent,
children,
callback,
);
} else {
root.render(children, callback);
}
});
}
return getPublicRootInstance(root._internalRoot);
}ReactRoot.render
这个函数做的事情:执行updateContainer
ReactRoot.prototype.render = function(
children: ReactNodeList,
callback: ?() => mixed,
): Work {
const root = this._internalRoot;
const work = new ReactWork();
callback = callback === undefined ? null : callback;
if (__DEV__) {
warnOnInvalidCallback(callback, 'render');
}
if (callback !== null) {
work.then(callback);
}
updateContainer(children, root, null, work._onCommit);
return work;
};updateContainer
这个函数做的事情:计算当前时间,超时时间,并传给updateContainerAtExpirationTime
export function updateContainer(
element: ReactNodeList,
container: OpaqueRoot,
parentComponent: ?React$Component<any, any>,
callback: ?Function,
): ExpirationTime {
const current = container.current;
const currentTime = requestCurrentTime();
const expirationTime = computeExpirationForFiber(currentTime, current);
return updateContainerAtExpirationTime(
element,
container,
parentComponent,
expirationTime,
callback,
);
}updateContainerAtExpirationTime
这个函数做的事情:执行scheduleRootUpdate,到这里我已经不明白了。
export function updateContainerAtExpirationTime(
element: ReactNodeList,
container: OpaqueRoot,
parentComponent: ?React$Component<any, any>,
expirationTime: ExpirationTime,
callback: ?Function,
) {
// TODO: If this is a nested container, this won't be the root.
const current = container.current;
const context = getContextForSubtree(parentComponent);
if (container.context === null) {
container.context = context;
} else {
container.pendingContext = context;
}
return scheduleRootUpdate(current, element, expirationTime, callback);
}scheduleRootUpdate
从这里开始我也不明白了,总之是调用scheduleWork,开始调度了。
function scheduleRootUpdate(
current: Fiber,
element: ReactNodeList,
expirationTime: ExpirationTime,
callback: ?Function,
) {
const update = createUpdate(expirationTime);
// Caution: React DevTools currently depends on this property
// being called "element".
update.payload = {element};
callback = callback === undefined ? null : callback;
flushPassiveEffects();
enqueueUpdate(current, update);
scheduleWork(current, expirationTime); // 最最最复杂的一块,开始调度
return expirationTime;
}共同學習,寫下你的評論
評論加載中...
作者其他優質文章