antd Modal 组件细节点
- 设置 destroyOnClose属性,关闭时销毁组件
- 这样重新进入Modal时就会再次挂载组件
- 否则会有缓存上一次的值 Bug
- 4x Modal内的表单,点击冒泡,会触发外层的 onClick
- 解决Modal外层包裹个 div
<div onClick={e => e.stopPropagation()}><Modal/></div>
- antd 5x Modal 没有这个问题
- 弹窗表单 ModalForm,只做弹窗的显示和隐藏,单一职责原则
- 隐藏 footer 默认底部的,确定取消按钮,取消 onCancel和 onOk,
- 省去 okButtonProps属性传递
```jsx
- 省去 okButtonProps属性传递
```jsx
<a name="zG4e6"></a>
## ProModal
```jsx
import {
useState,
cloneElement,
isValidElement,
forwardRef,
useImperativeHandle
} from 'react';
import {
number, bool, string, func, node, object, oneOfType
} from 'prop-types';
import { Modal, Button } from 'antd';
function RenderAction({element, onClick, buttonProps}) {
if(isValidElement(element)) {
return cloneElement(element, {
onClick,
});
}
if(buttonProps) {
return (
<Button
type={'primary'}
{...buttonProps}
onClick={onClick}
/>
)
}
return null;
}
function BaseModal(props, ref) {
const { children, element, text, buttonProps, ...rest } = props;
const [visible, setVisible] = useState(false);
useImperativeHandle(ref, () => ({
onShow,
onClose,
}));
function onShow() {
setVisible(true)
}
function onClose() {
setVisible(false);
}
return (
<>
<RenderAction
element={element}
buttonProps={buttonProps}
onClick={onShow}
/>
{
visible && (
<Modal
{...rest}
visible={visible}
// destroyOnClose
// maskClosable={false} 点击遮罩不关闭
// closable={false} 不显示标题右侧 x
>
{children}
</Modal>
)
}
</>
);
}
const BaseModalRef = forwardRef(BaseModal);
BaseModalRef.propTypes = {
title: node,
width: oneOfType([number, string]),
text: string,
onOk: func,
onCancel: func,
closable: bool,
destroyOnClose: bool,
buttonProps: object,
};
BaseModalRef.defaultProps = {
width: 560,
text: '新建',
closable: false,
destroyOnClose: true,
}
export default BaseModalRef;
使用 ProModal
import React, { useRef } from 'react';
import { func } from 'prop-types';
import { TagsOutlined } from '@ant-design/icons';
import { BaseModal } from '@/components'
BrandedAsTag.propTypes = {
onChange: func,
};
function BrandedAsTag({onChange}) {
const modalRef = useRef(null)
function onCancel() {
modalRef.current?.onClose();
}
function onOk() {
}
return (
<BaseModal
ref={modalRef}
title='会员打标签'
buttonProps={{
type: 'link',
size: 'small',
icon: <TagsOutlined />,
children: '打标签'
}}
onCancel={onCancel}
onOk={onOk}
>
123123
</BaseModal>
);
}
export default BrandedAsTag;
Modal 自定义 footer
footer: [
<Button
block
onClick={onCancel}
key='cancel'
>
取消
</Button>,
<Button
block
className="ml16"
type="primary"
onClick={onSubmit}
key='submit'
>
{okText}
</Button>
],