From c3d028d607ebf43bd7f375c88f989da46ae2feac Mon Sep 17 00:00:00 2001 From: gwsbhqt Date: Sat, 13 May 2023 19:57:32 +0800 Subject: [PATCH] fix: require react dom #3704 (#3818) * fix: require react dom #3704 * test: ignore load create portal function istanbul --- packages/react/src/shared/render.ts | 42 +++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/packages/react/src/shared/render.ts b/packages/react/src/shared/render.ts index c5eec08ec52..7b85c3985cd 100644 --- a/packages/react/src/shared/render.ts +++ b/packages/react/src/shared/render.ts @@ -1,21 +1,41 @@ -import React from 'react' +import React, { type ReactNode, type ReactPortal } from 'react' import { globalThisPolyfill } from '@formily/shared' -const env = { - portalDOM: null, - ReactDOM: null, +interface Env { + portalDOM?: HTMLDivElement + createPortal?: (children: ReactNode, container: Element) => ReactPortal +} + +const env: Env = { + portalDOM: globalThisPolyfill?.document?.createElement?.('div'), + createPortal: globalThisPolyfill?.['ReactDOM']?.createPortal, +} + +/* istanbul ignore next */ +const loadCreatePortal = () => { + if (!env.createPortal) { + try { + // eslint-disable-next-line @typescript-eslint/no-var-requires + env.createPortal ??= require('react-dom')?.createPortal + } catch {} + } + if (!env.createPortal) { + try { + // @ts-ignore + import('react-dom') + .then((module) => (env.createPortal ??= module?.createPortal)) + .catch() + } catch {} + } } export const render = (element: React.ReactElement) => { if (globalThisPolyfill.navigator?.product === 'ReactNative') return null - if (globalThisPolyfill.document) { - env.portalDOM = - env.portalDOM || globalThisPolyfill['document'].createElement('div') - env.ReactDOM = - env.ReactDOM || globalThisPolyfill['ReactDOM'] || require('react-dom') - //eslint-disable-next-line - return env.ReactDOM.createPortal(element, env.portalDOM) + if (env.portalDOM && env.createPortal) { + return env.createPortal(element, env.portalDOM) } else { return React.createElement('template', {}, element) } } + +loadCreatePortal()