import React, { useRef, useMemo, memo, forwardRef, useCallback, useState, useImperativeHandle, useId } from 'react' import { Modal, Form } from 'antd' import type { ModalProps } from 'antd' const MyModal = memo( forwardRef((prop: any, ref) => { const [form] = Form.useForm() const [modalChildren, setModalChildren] = useState(null) const [loading, setLoading] = useState(false) const [modalProps, setModalProps] = useState({ visible: false }) const typeRef = useRef() const onFinish = useCallback( (values: any) => { const response = modalProps.onOk?.(values) if (response instanceof Promise) { setLoading(true) response.finally(() => { setLoading(false) }) } }, [form, modalProps] ) // ant.design 4.0 Form的onFinish触发回调 // const onFinish = useCallback( // (values: any) => { // modalProps.onOk?.(values) // }, // [form, modalProps] // ) // 关闭当前Modal const onClose = useCallback(() => { setModalProps(source => ({ ...source, visible: false })) }, [form]) // 关闭当前Modal const onOpen = useCallback(() => { setModalProps(source => ({ ...source, visible: true })) }, [form]) useImperativeHandle( ref, () => ({ // 注入Modal的子组件 injectChildren: element => { setModalChildren(element) }, // 注入Modal参数 injectModalProps: props => { console.log(props) setModalProps(source => { return { ...source, ...props } }) }, // 打开Modal open: () => { onOpen() }, // 关闭Modal close: () => { if (loading) setLoading(false) onClose() }, // 设置表单数据 setFieldsValue: (values: any) => { form.setFieldsValue?.(values) }, setType: (type: string) => { typeRef.current = type } }), [] ) const handleOk = useCallback(() => { if (typeRef.current === 'form') { form.submit() } else { modalProps.onOk?.(null) } }, [form, modalProps]) // 这里的Modal是ant.design中的Modal return ( {modalChildren ? React.cloneElement(modalChildren, { onFinish, form, onClose }) : null} ) }) ) interface modalRefType { open: () => void close: () => void injectChildren: (child: React.ReactElement) => void injectModalProps: (props: ModalProps) => void setFieldsValue: (values: any) => void setType: (type: string) => void } interface OpenArgType extends ModalProps { children?: React.ReactElement type?: 'form' | 'default' initialValues?: { [key: string]: any } } /** * 适用于单弹窗模式 */ const useModal = () => { const modalRef = useRef() const handle = useMemo(() => { return { open: ({ children, type, initialValues, ...rest }: OpenArgType) => { modalRef.current.setType(type) modalRef.current.injectChildren(children) // 注入子组件 modalRef.current.injectModalProps(rest) // 注入Modal的参数 modalRef.current.open() if (initialValues && type === 'form') { modalRef.current.setFieldsValue?.(initialValues) } }, close: () => { modalRef.current.close() } } }, []) return [handle, ] as const } export type ModalAction = { open: (args: OpenArgType) => void close: () => void } export default useModal