UNPKG

vtils

Version:

一个面向业务的 JavaScript/TypeScript 实用程序库。

107 lines (106 loc) 3.55 kB
import _extends from "@babel/runtime/helpers/esm/extends"; import React from 'react'; import ReactDOM from 'react-dom'; import { isPromiseLike } from "../utils/index.js"; import { useUpdate } from 'react-use'; /** * 独立渲染一个组件在 document.body 下,常应用于弹窗类组件。 * * @param Component 要渲染的组件 * @param initialProps 初始属性 * @param injectCallbacks 回调函数注入 */ export function renderComponent(Component, initialProps, injectCallbacks) { var hasContainer = true; var render; var destroy; var prepareProps = function prepareProps(props) { props = _extends({}, props); if (injectCallbacks) { var _loop = function _loop() { var key = _Object$keys[_i]; var originalCallback = props[key]; props[key] = function () { var res = originalCallback == null ? void 0 : originalCallback(); if (isPromiseLike(res)) { return res.then(function () { return injectCallbacks[key](); }); } return injectCallbacks[key](); }; }; for (var _i = 0, _Object$keys = Object.keys(injectCallbacks); _i < _Object$keys.length; _i++) { _loop(); } } return props; }; if (hasRenderComponentContainer) { var childIndex; render = function render(props) { props = prepareProps(props); if (childIndex == null) { childIndex = renderComponentContainerChildren.length; renderComponentContainerChildren.push(React.createElement(Component, props)); } else { renderComponentContainerChildren.splice(childIndex, 1, React.createElement(Component, props)); } updateRenderComponentContainer(); }; destroy = function destroy() { if (childIndex != null) { renderComponentContainerChildren.splice(childIndex, 1); updateRenderComponentContainer(); } }; } else { var container = document.createElement('div'); document.body.appendChild(container); render = function render(props) { props = prepareProps(props); ReactDOM.render(React.createElement(Component, props), container); }; destroy = function destroy() { if (!hasContainer || !container) return; var unmountResult = ReactDOM.unmountComponentAtNode(container); if (unmountResult) { var _container$parentNode; (_container$parentNode = container.parentNode) == null || _container$parentNode.removeChild(container); } container = null; hasContainer = false; }; } var incrementalProps = _extends({ key: Date.now() }, initialProps); render(incrementalProps); return { incrementalRerender: function incrementalRerender(props) { if (!hasContainer) return; incrementalProps = _extends({}, incrementalProps, props); render(incrementalProps); }, partialRerender: function partialRerender(props) { if (!hasContainer) return; render(_extends({}, initialProps, props)); }, fullRerender: function fullRerender(props) { if (!hasContainer) return; render(props); }, destroy: destroy }; } // 渲染容器 var hasRenderComponentContainer = false; var updateRenderComponentContainer; var renderComponentContainerChildren = []; export function RenderComponentContainer() { hasRenderComponentContainer = true; updateRenderComponentContainer = useUpdate(); return React.createElement(React.Fragment, { children: renderComponentContainerChildren }); }