react是如何生成頁面的呢雄嚣?從react框架的入口可以看到app.js的內(nèi)容是
ReactDOM.render(
<Home/>
)
從源碼的reactDOM.js中找到render:
const ReactDOM: Object = {
.....
render(
//元素
element: React$Element<any>,
//根節(jié)點(diǎn)
container: DOMContainer,
//回調(diào)函數(shù)
callback: ?Function,
) {
invariant(
isValidContainer(container),
'Target container is not a DOM element.',
);
if (__DEV__) {
//校驗(yàn)container參數(shù)
warningWithoutStack(
!container._reactHasBeenPassedToCreateRootDEV,
'You are calling ReactDOM.render() on a container that was previously ' +
'passed to ReactDOM.%s(). This is not supported. ' +
'Did you mean to call root.render(element)?',
enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot',
);
}
//調(diào)用legacyRenderSubtreeIntoContainer方法并返回
return legacyRenderSubtreeIntoContainer(
null,
element,
container,
false,
callback,
);
},
.....
}
render最終返回的legacyRenderSubtreeIntoContainer函數(shù)
function legacyRenderSubtreeIntoContainer(
parentComponent: ?React$Component<any, any>, //父組件,沒有就傳null
children: ReactNodeList, //子元素
container: DOMContainer,//根節(jié)點(diǎn)
forceHydrate: boolean,//協(xié)調(diào)更新 false
callback: ?Function, //回調(diào)函數(shù)
) {
if (__DEV__) {
topLevelUpdateWarnings(container);
warnOnInvalidCallback(callback === undefined ? null : callback, 'render');
}
// TODO: Without `any` type, Flow says "Property cannot be accessed on any
// member of intersection type." Whyyyyyy.
let root: _ReactSyncRoot = (container._reactRootContainer: any);
let fiberRoot;
//第一次渲染的時(shí)候沒有已存在的root
if (!root) {
// Initial mount
// 創(chuàng)建 root
root = container._reactRootContainer = legacyCreateRootFromDOMContainer(
container,
forceHydrate,
);
fiberRoot = root._internalRoot;
//執(zhí)行回調(diào)
if (typeof callback === 'function') {
const originalCallback = callback;
callback = function() {
const instance = getPublicRootInstance(fiberRoot);
originalCallback.call(instance);
};
}
// Initial mount should not be batched.
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);
};
}
// Update
updateContainer(children, fiberRoot, parentComponent, callback);
}
return getPublicRootInstance(fiberRoot);
}