UNPKG

@antv/s2-react

Version:
119 lines 4.56 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.forceClearContent = exports.reactUnmount = exports.reactRender = exports.isLegacyReactVersion = exports.S2_REACT_ROOT_SYMBOL_ID = void 0; const tslib_1 = require("tslib"); /** * 兼容 React 16/17/18/19 的挂载和卸载 */ const react_1 = require("react"); const ReactDOM = tslib_1.__importStar(require("react-dom")); exports.S2_REACT_ROOT_SYMBOL_ID = `__s2_react_root__`; // 1. 避免直接解构 render,防止 React 19 报错 // 仅保留类型定义和必要的静态属性引用 const ReactDOMClone = Object.assign({}, ReactDOM); let createRootFn; // 2. 异步获取 createRoot // 这是一个懒加载单例,只在第一次渲染时执行 function getCreateRoot() { return tslib_1.__awaiter(this, void 0, void 0, function* () { if (createRootFn) { return createRootFn; } // 优先尝试 React 18 的同步入口 (如果有) if (ReactDOMClone.createRoot) { createRootFn = ReactDOMClone.createRoot; return createRootFn; } // React 19+ 或 React 18 Client 模式 try { const client = yield Promise.resolve().then(() => tslib_1.__importStar(require('react-dom/client'))); createRootFn = client.createRoot; return createRootFn; } catch (e) { throw new Error('[S2] React 18+ detected but failed to load createRoot. Please ensure react-dom is installed correctly.', { cause: e }); } }); } const isLegacyReactVersion = () => { const mainVersion = Number((react_1.version || '').split('.')[0]); return mainVersion < 18; }; exports.isLegacyReactVersion = isLegacyReactVersion; /** * 由于兼容的关系, 没有从 "react-dom/client" 引入 createRoot, 会报 warning * https://github.com/facebook/react/issues/24372 */ function toggleWarning(skip) { const { __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED } = ReactDOMClone; 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; } } // ========================== Render ========================== function modernRender(node, container) { return tslib_1.__awaiter(this, void 0, void 0, function* () { toggleWarning(true); let root = container[exports.S2_REACT_ROOT_SYMBOL_ID]; if (!root) { // 异步等待 createRoot 加载完成 const createRoot = yield getCreateRoot(); root = createRoot(container); container[exports.S2_REACT_ROOT_SYMBOL_ID] = root; } toggleWarning(false); root.render(node); return root; }); } function legacyRender(node, container) { const reactRender = ReactDOMClone.render; if (reactRender) { reactRender(node, container); } else { throw new Error('[S2] Failed to render. React 16/17 detected but ReactDOM.render is empty'); } } // 注意:这里变成了 async 函数 function reactRender(node, container) { return tslib_1.__awaiter(this, void 0, void 0, function* () { if (!(0, exports.isLegacyReactVersion)()) { yield modernRender(node, container); return; } legacyRender(node, container); }); } exports.reactRender = reactRender; // ========================= Unmount ========================== function modernUnmount(container) { return Promise.resolve().then(() => { var _a; (_a = container === null || container === void 0 ? void 0 : container[exports.S2_REACT_ROOT_SYMBOL_ID]) === null || _a === void 0 ? void 0 : _a.unmount(); container === null || container === void 0 ? true : delete container[exports.S2_REACT_ROOT_SYMBOL_ID]; }); } function legacyUnmount(container) { const unmount = ReactDOMClone.unmountComponentAtNode; if (container && unmount) { unmount(container); } } function reactUnmount(container) { if (!(0, exports.isLegacyReactVersion)()) { return modernUnmount(container); } return legacyUnmount(container); } exports.reactUnmount = reactUnmount; function forceClearContent(container) { if ((0, exports.isLegacyReactVersion)()) { return legacyUnmount(container); } return modernRender(null, container); } exports.forceClearContent = forceClearContent; //# sourceMappingURL=reactRender.js.map