├─RiskModal
│ index.js //将riskModal与show等方法结合起来并导出
│ riskModal.js //自定义Modal
│ riskModal.less
│ show.js //命令时调用
import { Modal } from 'antd-mobile';
const RiskModal = ({
visible,
onClose,
...
}) => {
...
return (
<Modal visible={visible} onClose={onClose}>
...自定义样式
</Modal>)
}
以前多数情况下,都是在父函数式组件中作为组件去调用,每次都需要定义visible状态并传入。
import { renderImperatively } from '@/utils/render-imperatively';
export const show = (props) => {
return renderImperatively(
<RiskModal
{...props}
/>,
);
};
import React, { useEffect, useImperativeHandle, useRef, useState } from 'react';
import { renderToBody } from '@/utils/renderToBody';
import { isFunction } from 'lodash';
export function renderImperatively(element) {
//Wrapper组件单独维护一个visible状态,React.forwardRef主要是用来暴露close方法给父组件调用
const Wrapper = React.forwardRef((_, ref) => {
const [visible, setVisible] = useState(false);
const closedRef = useRef(false);
//初始化组件时修改展示状态
useEffect(() => {
if (!closedRef.current) {
setVisible(true);
} else {
afterClose();
}
}, []);
function onClose() {
closedRef.current = true;
setVisible(false);
if (isFunction(element?.props?.onClose))
element.props.onClose();
}
function afterClose() {
unmount();
if (isFunction(element?.props?.onClose))
element.props.onClose();
}
useImperativeHandle(ref, () => ({
close: onClose,
}));
return React.cloneElement(element, {
...element.props,
visible,
onClose,
afterClose,
});
});
const wrapperRef = React.createRef();
//将新复制的组件挂载到body上,重点其实是这个
const unmount = renderToBody(<Wrapper ref={wrapperRef} />);
function close() {
if (isFunction(wrapperRef?.current?.close))
wrapperRef.current.close();
}
return {
close,
};
}
import ReactDOM from 'react-dom';
export const renderToBody = (element) => {
const container = document.createElement('div');
document.body.appendChild(container);
function unmount() {
const unmountResult = ReactDOM.unmountComponentAtNode(container);
if (unmountResult && container.parentNode) {
container.parentNode.removeChild(container);
}
}
ReactDOM.render(element, container);
return unmount;
};
import RiskModal from './riskModal';
import { show } from './show';
import { attachPropertiesToComponent } from '@/utils/attach-properties-to-component';
export default attachPropertiesToComponent(RiskModal, {
show,
});
export const attachPropertiesToComponent = (component, properties) => {
const ret = component;
for (const key in properties) {
if (properties.hasOwnProperty(key)) {
ret[key] = properties[key];
}
}
return ret;
};
import RiskModal from '@/components/RiskModal';
RiskModal.show({
type,
});