vtils
Version:
一个面向业务的 JavaScript/TypeScript 实用程序库。
113 lines (111 loc) • 3.99 kB
JavaScript
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
exports.__esModule = true;
exports.RenderComponentContainer = RenderComponentContainer;
exports.renderComponent = renderComponent;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _react = _interopRequireDefault(require("react"));
var _reactDom = _interopRequireDefault(require("react-dom"));
var _utils = require("../utils");
var _reactUse = require("react-use");
/**
* 独立渲染一个组件在 document.body 下,常应用于弹窗类组件。
*
* @param Component 要渲染的组件
* @param initialProps 初始属性
* @param injectCallbacks 回调函数注入
*/
function renderComponent(Component, initialProps, injectCallbacks) {
var hasContainer = true;
var render;
var destroy;
var prepareProps = function prepareProps(props) {
props = (0, _extends2.default)({}, 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 ((0, _utils.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.default.createElement(Component, props));
} else {
renderComponentContainerChildren.splice(childIndex, 1, _react.default.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.default.render(_react.default.createElement(Component, props), container);
};
destroy = function destroy() {
if (!hasContainer || !container) return;
var unmountResult = _reactDom.default.unmountComponentAtNode(container);
if (unmountResult) {
var _container$parentNode;
(_container$parentNode = container.parentNode) == null || _container$parentNode.removeChild(container);
}
container = null;
hasContainer = false;
};
}
var incrementalProps = (0, _extends2.default)({
key: Date.now()
}, initialProps);
render(incrementalProps);
return {
incrementalRerender: function incrementalRerender(props) {
if (!hasContainer) return;
incrementalProps = (0, _extends2.default)({}, incrementalProps, props);
render(incrementalProps);
},
partialRerender: function partialRerender(props) {
if (!hasContainer) return;
render((0, _extends2.default)({}, initialProps, props));
},
fullRerender: function fullRerender(props) {
if (!hasContainer) return;
render(props);
},
destroy: destroy
};
}
// 渲染容器
var hasRenderComponentContainer = false;
var updateRenderComponentContainer;
var renderComponentContainerChildren = [];
function RenderComponentContainer() {
hasRenderComponentContainer = true;
updateRenderComponentContainer = (0, _reactUse.useUpdate)();
return _react.default.createElement(_react.default.Fragment, {
children: renderComponentContainerChildren
});
}
;