diff --git a/package.json b/package.json index fcf55298..91d059fd 100644 --- a/package.json +++ b/package.json @@ -32,8 +32,8 @@ "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^13.0.0", "@types/jest": "^25.2.3", - "@types/react": "^17.0.43", - "@types/react-dom": "^17.0.14", + "@types/react": "^18.0.0", + "@types/react-dom": "^18.0.0", "@types/shallowequal": "^1.1.1", "@types/warning": "^3.0.0", "@umijs/fabric": "^2.0.8", diff --git a/src/React/render.ts b/src/React/render.ts index 05f74e3d..34a749d3 100644 --- a/src/React/render.ts +++ b/src/React/render.ts @@ -1,21 +1,45 @@ import type * as React from 'react'; -import { +import * as ReactDOM from 'react-dom'; +import type { Root } from 'react-dom/client'; + +type CreateRoot = (container: ContainerType) => Root; + +type InternalReactDOM = typeof ReactDOM & { + __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED?: { + usingClientEntryPoint?: boolean; + }; + createRoot?: CreateRoot; +}; + +const { version, - render as reactRender, + render: reactRender, unmountComponentAtNode, -} from 'react-dom'; -import type { Root } from 'react-dom/client'; +} = ReactDOM as InternalReactDOM; -let createRoot: (container: ContainerType) => Root; +let createRoot: CreateRoot; try { const mainVersion = Number((version || '').split('.')[0]); if (mainVersion >= 18) { - ({ createRoot } = require('react-dom/client')); + ({ createRoot } = ReactDOM as InternalReactDOM); } } catch (e) { // Do nothing; } +function toggleWarning(skip: boolean) { + const { __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED } = + ReactDOM as InternalReactDOM; + + if ( + __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED && + typeof __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED === 'object' + ) { + __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.usingClientEntryPoint = + skip; + } +} + const MARK = '__rc_react_root__'; // ========================== Render ========================== @@ -24,7 +48,10 @@ type ContainerType = (Element | DocumentFragment) & { }; function modernRender(node: React.ReactElement, container: ContainerType) { + toggleWarning(true); const root = container[MARK] || createRoot(container); + toggleWarning(false); + root.render(node); container[MARK] = root; diff --git a/tests/react.test.tsx b/tests/react.test.tsx index 1df19531..cd1d9a77 100644 --- a/tests/react.test.tsx +++ b/tests/react.test.tsx @@ -12,6 +12,8 @@ describe('React', () => { }); it('render & unmount', async () => { + const errorSpy = jest.spyOn(console, 'error'); + const div = document.createElement('div'); document.body.appendChild(div); @@ -26,6 +28,8 @@ describe('React', () => { await unmount(div); }); expect(div.querySelector('.bamboo')).toBeFalsy(); + + expect(errorSpy).not.toHaveBeenCalled(); }); it('React 17 render & unmount', async () => {