in packages/react/react-portal/src/mount.tsx [57:170]
export function mount<T extends EmitterProps>(App: AppComponent<T>, container?: Element | null, id?: string) {
class ConsoleApp extends React.Component<EmitterProps & IProps> {
constructor(props) {
super(props);
// @deprecated
if (props.__enableInitialHistoryAction && props?.appProps?.path && props?.appProps?.path !== getPathNameWithQueryAndSearch()) {
window.history.replaceState(null, null, props?.appProps?.path);
}
}
componentDidCatch() { /* Empty */ }
componentDidMount() { /* Empty */ }
componentWillUnmount() { /* Empty */ }
render() {
const props = getProps(this.props);
const { logger, appDidCatch } = props;
const contextValue: IContextProps = {
inOsSandBox: isOsContext(),
appProps: props,
};
return (
<ErrorBoundary
logger={logger}
appDidCatch={appDidCatch}
>
{ Context ? (
<Context.Provider value={contextValue}>
<App {...Object.assign(props || {})} />
</Context.Provider>
) : <App {...Object.assign(props || {})} />
}
</ErrorBoundary>
);
}
}
// 如果外部被其他沙箱嵌套,沙箱销毁时一旦清除全局变量,isOsBundle 拿到的值将为 false
// 需要综合判断
if (isOsBundle() || isOsContext() || isAlfaScript()) {
const reactLifeCycles = SingleSpaReact({
React,
ReactDOM,
rootComponent: ConsoleApp,
domElementGetter: () => document.getElementsByTagName(id)[0],
});
/**
* 针对 外跳 的路由提供简单的方式通知宿主
* @param e 点击事件
*/
let handleExternalLinks;
return {
bootstrap: [
reactLifeCycles.bootstrap,
],
mount: [
reactLifeCycles.mount,
// 全局事件托管
async (props) => {
const { domElement } = props;
const { emitter, name } = getProps(props);
bindEvents(emitter);
if (isOsContext()) {
handleExternalLinks = (e: Event) => {
const target = e.target as HTMLAnchorElement;
if (target.tagName === 'A' && target.hasAttribute('data-alfa-external-router')) {
e.preventDefault();
e.stopPropagation();
emitter && emitter.emit(`${name || id}:external-router`, target.getAttribute('href'));
}
};
domElement?.addEventListener('click', handleExternalLinks, true);
}
},
],
unmount: [
// 注销全局事件托管
async (props) => {
const { domElement } = props;
const { emitter } = getProps(props);
unbindEvents(emitter);
if (isOsContext() && handleExternalLinks) {
domElement?.removeEventListener('click', handleExternalLinks, true);
handleExternalLinks = undefined;
}
},
reactLifeCycles.unmount,
],
update: [
reactLifeCycles.update,
],
exposedModule: exposeModuleMap,
};
} else {
// @ts-ignore;
if (ReactDOM.createRoot) {
// @ts-ignore;
ReactDOM.createRoot(container).render(<ConsoleApp />);
return;
}
ReactDOM.render(<ConsoleApp />, container);
}
}