11import * as React from 'react' ;
22
3- let version = React . version || ''
3+ const MARK = '__rc_react_root__' ;
4+
5+ type RootType = {
6+ render : ( node : React . ReactNode ) => void ;
7+ unmount : ( ) => void ;
8+ } ;
49
5- let createRoot : ( ( container : Element | DocumentFragment ) => any ) | undefined ;
10+ type ContainerType = ( Element | DocumentFragment ) & {
11+ [ MARK ] ?: RootType ;
12+ } ;
13+
14+ let createRoot : ( ( container : Element | DocumentFragment ) => RootType ) | undefined ;
615let legacyRender : ( ( node : React . ReactElement , container : Element | DocumentFragment ) => void ) | undefined ;
716let legacyUnmount : ( ( container : Element | DocumentFragment ) => boolean ) | undefined ;
817
9- const MARK = '__rc_react_root__' ;
18+ let initialized = false ;
1019
11- type ContainerType = ( Element | DocumentFragment ) & {
12- [ MARK ] ?: ReturnType < NonNullable < typeof createRoot > > ;
13- } ;
20+ async function ensureReactDOM ( ) {
21+ if ( initialized ) return ;
22+ initialized = true ;
1423
15- try {
16- const mainVersion = parseInt ( version . split ( '.' ) [ 0 ] , 10 ) ;
24+ try {
25+ const version = React . version || '' ;
26+ const mainVersion = parseInt ( version . split ( '.' ) [ 0 ] , 10 ) ;
1727
18- if ( mainVersion >= 18 ) {
19- // 动态引入 React 18+ 的 API
20- const client = require ( 'react-dom/client' ) ;
21- createRoot = client . createRoot ;
22- } else {
23- // 仅在 React <18 才有 render/unmountComponentAtNode
24- const legacyReactDOM = require ( 'react-dom' ) ;
25- legacyRender = legacyReactDOM . render ;
26- legacyUnmount = legacyReactDOM . unmountComponentAtNode ;
28+ if ( mainVersion >= 18 ) {
29+ const client = await import ( 'react-dom/client' ) ;
30+ createRoot = client . createRoot ;
31+ } else {
32+ const legacy = await import ( 'react-dom' ) ;
33+ legacyRender = legacy . render ;
34+ legacyUnmount = legacy . unmountComponentAtNode ;
35+ }
36+ } catch ( e ) {
37+ console . warn ( '[react-render] Failed to load ReactDOM API:' , e ) ;
2738 }
28- } catch ( e ) {
29- // 忽略错误
3039}
3140
3241// ========== 渲染 ==========
@@ -38,41 +47,29 @@ function modernRender(node: React.ReactNode, container: ContainerType) {
3847}
3948
4049function fallbackLegacyRender ( node : React . ReactElement , container : ContainerType ) {
41- if ( legacyRender ) {
42- legacyRender ( node , container ) ;
43- } else {
44- throw new Error ( 'ReactDOM.render is not available in this React version' ) ;
45- }
50+ if ( ! legacyRender ) throw new Error ( 'ReactDOM.render not available' ) ;
51+ legacyRender ( node , container ) ;
4652}
4753
48- export function render ( node : React . ReactElement , container : ContainerType ) {
49- if ( createRoot ) {
50- modernRender ( node , container ) ;
51- } else {
52- fallbackLegacyRender ( node , container ) ;
53- }
54+ export async function render ( node : React . ReactElement , container : ContainerType ) {
55+ await ensureReactDOM ( ) ;
56+ if ( createRoot ) modernRender ( node , container ) ;
57+ else fallbackLegacyRender ( node , container ) ;
5458}
5559
5660// ========== 卸载 ==========
5761function fallbackLegacyUnmount ( container : ContainerType ) {
58- if ( legacyUnmount ) {
59- legacyUnmount ( container ) ;
60- } else {
61- throw new Error ( 'ReactDOM.unmountComponentAtNode is not available in this React version' ) ;
62- }
62+ if ( ! legacyUnmount ) throw new Error ( 'ReactDOM.unmountComponentAtNode not available' ) ;
63+ legacyUnmount ( container ) ;
6364}
6465
6566async function modernUnmount ( container : ContainerType ) {
66- return Promise . resolve ( ) . then ( ( ) => {
67- container [ MARK ] ?. unmount ?.( ) ;
68- delete container [ MARK ] ;
69- } ) ;
67+ container [ MARK ] ?. unmount ?.( ) ;
68+ delete container [ MARK ] ;
7069}
7170
7271export async function unmount ( container : ContainerType ) {
73- if ( createRoot ) {
74- return modernUnmount ( container ) ;
75- } else {
76- return fallbackLegacyUnmount ( container ) ;
77- }
72+ await ensureReactDOM ( ) ;
73+ if ( createRoot ) return modernUnmount ( container ) ;
74+ else return fallbackLegacyUnmount ( container ) ;
7875}
0 commit comments