import React from 'react';
import {useContext, useMemo, useRef, useState, useLayoutEffect} from 'react';
import {__RouterContext} from 'react-router';
import {ReactReduxContext} from 'react-redux';
import ThemeContext from './shared/ThemeContext';
let rendererModule = {
status: 'pending',
promise: null,
result: null,
};
export default function lazyLegacyRoot(getLegacyComponent) {
let componentModule = {
status: 'pending',
promise: null,
result: null,
};
return function Wrapper(props) {
const createLegacyRoot = readModule(
rendererModule,
() => import('../legacy/createLegacyRoot')
).default;
const Component = readModule(componentModule, getLegacyComponent).default;
const containerRef = useRef(null);
const rootRef = useRef(null);
const theme = useContext(ThemeContext);
const router = useContext(__RouterContext);
const reactRedux = useContext(ReactReduxContext);
const context = useMemo(
() => ({
theme,
router,
reactRedux,
}),
[theme, router, reactRedux]
);
useLayoutEffect(() => {
if (!rootRef.current) {
rootRef.current = createLegacyRoot(containerRef.current);
}
const root = rootRef.current;
return () => {
root.unmount();
};
}, [createLegacyRoot]);
useLayoutEffect(() => {
if (rootRef.current) {
rootRef.current.render(Component, props, context);
}
}, [Component, props, context]);
return <div style={{display: 'contents'}} ref={containerRef} />;
};
}
function readModule(record, createPromise) {
if (record.status === 'fulfilled') {
return record.result;
}
if (record.status === 'rejected') {
throw record.result;
}
if (!record.promise) {
record.promise = createPromise().then(
value => {
if (record.status === 'pending') {
record.status = 'fulfilled';
record.promise = null;
record.result = value;
}
},
error => {
if (record.status === 'pending') {
record.status = 'rejected';
record.promise = null;
record.result = error;
}
}
);
}
throw record.promise;
}