|
1 |
| -import type { ReactElement } from 'react'; |
2 |
| -import ReactDOM from 'react-dom'; |
3 |
| -import type { RenderReturnType } from './types'; |
4 |
| - |
5 |
| -type HydrateOrRenderType = (domNode: Element, reactElement: ReactElement) => RenderReturnType; |
6 |
| -const supportsReactCreateRoot = ReactDOM.version && |
7 |
| - parseInt(ReactDOM.version.split('.')[0], 10) >= 18; |
8 |
| - |
9 |
| -// TODO: once React dependency is updated to >= 18, we can remove this and just |
10 |
| -// import ReactDOM from 'react-dom/client'; |
11 |
| -// eslint-disable-next-line @typescript-eslint/no-explicit-any |
12 |
| -let reactDomClient: any; |
13 |
| -if (supportsReactCreateRoot) { |
14 |
| - // This will never throw an exception, but it's the way to tell Webpack the dependency is optional |
15 |
| - // https://github.com/webpack/webpack/issues/339#issuecomment-47739112 |
16 |
| - // Unfortunately, it only converts the error to a warning. |
17 |
| - try { |
18 |
| - // eslint-disable-next-line global-require,import/no-unresolved |
19 |
| - reactDomClient = require('react-dom/client'); |
20 |
| - } catch (e) { |
21 |
| - // We should never get here, but if we do, we'll just use the default ReactDOM |
22 |
| - // and live with the warning. |
23 |
| - reactDomClient = ReactDOM; |
24 |
| - } |
25 |
| -} |
26 |
| - |
27 |
| -export const reactHydrate: HydrateOrRenderType = supportsReactCreateRoot ? |
28 |
| - reactDomClient.hydrateRoot : |
29 |
| - (domNode, reactElement) => ReactDOM.hydrate(reactElement, domNode); |
30 |
| - |
31 |
| -export function reactRender(domNode: Element, reactElement: ReactElement): RenderReturnType { |
32 |
| - if (supportsReactCreateRoot) { |
33 |
| - const root = reactDomClient.createRoot(domNode); |
34 |
| - root.render(reactElement); |
35 |
| - return root; |
36 |
| - } |
37 |
| - |
38 |
| - // eslint-disable-next-line react/no-render-return-value |
39 |
| - return ReactDOM.render(reactElement, domNode); |
40 |
| -} |
41 |
| - |
42 |
| -export default function reactHydrateOrRender(domNode: Element, reactElement: ReactElement, hydrate: boolean): RenderReturnType { |
43 |
| - return hydrate ? reactHydrate(domNode, reactElement) : reactRender(domNode, reactElement); |
44 |
| -} |
| 1 | +import type { ReactElement } from 'react'; |
| 2 | +import ReactDOM from 'react-dom'; |
| 3 | +import type { RenderReturnType } from './types'; |
| 4 | +import { supportsRootApi } from './reactApis'; |
| 5 | + |
| 6 | +type HydrateOrRenderType = (domNode: Element, reactElement: ReactElement) => RenderReturnType; |
| 7 | + |
| 8 | +// TODO: once React dependency is updated to >= 18, we can remove this and just |
| 9 | +// import ReactDOM from 'react-dom/client'; |
| 10 | +// eslint-disable-next-line @typescript-eslint/no-explicit-any |
| 11 | +let reactDomClient: any; |
| 12 | +if (supportsRootApi) { |
| 13 | + // This will never throw an exception, but it's the way to tell Webpack the dependency is optional |
| 14 | + // https://github.com/webpack/webpack/issues/339#issuecomment-47739112 |
| 15 | + // Unfortunately, it only converts the error to a warning. |
| 16 | + try { |
| 17 | + // eslint-disable-next-line global-require,import/no-unresolved |
| 18 | + reactDomClient = require('react-dom/client'); |
| 19 | + } catch (e) { |
| 20 | + // We should never get here, but if we do, we'll just use the default ReactDOM |
| 21 | + // and live with the warning. |
| 22 | + reactDomClient = ReactDOM; |
| 23 | + } |
| 24 | +} |
| 25 | + |
| 26 | +export const reactHydrate: HydrateOrRenderType = supportsRootApi ? |
| 27 | + reactDomClient.hydrateRoot : |
| 28 | + (domNode, reactElement) => ReactDOM.hydrate(reactElement, domNode); |
| 29 | + |
| 30 | +export function reactRender(domNode: Element, reactElement: ReactElement): RenderReturnType { |
| 31 | + if (supportsRootApi) { |
| 32 | + const root = reactDomClient.createRoot(domNode); |
| 33 | + root.render(reactElement); |
| 34 | + return root; |
| 35 | + } |
| 36 | + |
| 37 | + // eslint-disable-next-line react/no-render-return-value |
| 38 | + return ReactDOM.render(reactElement, domNode); |
| 39 | +} |
| 40 | + |
| 41 | +export default function reactHydrateOrRender(domNode: Element, reactElement: ReactElement, hydrate: boolean): RenderReturnType { |
| 42 | + return hydrate ? reactHydrate(domNode, reactElement) : reactRender(domNode, reactElement); |
| 43 | +} |
0 commit comments