import React from 'react'; import ReactDOM from 'react-dom'; type MountHandle = { render: (element: React.ReactElement) => void, unmount: () => void, }; /** * 尝试加载 react-dom/client 模块。 * @returns client 模块或 null */ function loadReactDomClient(): { createRoot?: (container: HTMLElement) => { render: (el: React.ReactElement) => void, unmount: () => void, } } | null { try { // eslint-disable-next-line global-require, import/no-extraneous-dependencies return require('react-dom/client'); } catch (error) { return null; } } /** * 创建兼容 React 16/17/18 的挂载句柄。 * @param container - 挂载容器 * @param loadClient - 可选 client 加载器,便于测试注入 * @returns 渲染与卸载方法 */ function createMountHandle( container: HTMLElement, loadClient: typeof loadReactDomClient = loadReactDomClient, ): MountHandle { let root: { render: (el: React.ReactElement) => void, unmount: () => void } | null = null; const client = loadClient(); if (client && typeof client.createRoot === 'function') { root = client.createRoot(container); return { render: (element) => root!.render(element), unmount: () => root!.unmount(), }; } return { render: (element) => { ReactDOM.render(element, container); }, unmount: () => { ReactDOM.unmountComponentAtNode(container); }, }; } export { createMountHandle, loadReactDomClient, };