react是如何生成页面的呢?从react框架的入口可以看到app.js的内容是
ReactDOM.render(
<Home/>
)
从源码的reactDOM.js中找到render:
const ReactDOM: Object = {
.....
render(
//元素
element: React$Element<any>,
//根节点
container: DOMContainer,
//回调函数
callback: ?Function,
) {
invariant(
isValidContainer(container),
'Target container is not a DOM element.',
);
if (__DEV__) {
//校验container参数
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',
);
}
//调用legacyRenderSubtreeIntoContainer方法并返回
return legacyRenderSubtreeIntoContainer(
null,
element,
container,
false,
callback,
);
},
.....
}
render最终返回的legacyRenderSubtreeIntoContainer函数
function legacyRenderSubtreeIntoContainer(
parentComponent: ?React$Component<any, any>, //父组件,没有就传null
children: ReactNodeList, //子元素
container: DOMContainer,//根节点
forceHydrate: boolean,//协调更新 false
callback: ?Function, //回调函数
) {
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;
//第一次渲染的时候没有已存在的root
if (!root) {
// Initial mount
// 创建 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);
};
}
// 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);
}
网友评论