Skip to content

Instantly share code, notes, and snippets.

@iShawnWang
Last active October 31, 2021 05:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iShawnWang/95d40403870f27970d84f0a2395d46dc to your computer and use it in GitHub Desktop.
Save iShawnWang/95d40403870f27970d84f0a2395d46dc to your computer and use it in GitHub Desktop.
Use Ant Design Modal in Imperative Mode
import {ModalProvider, ModalContext, Modalman} from './Modalman'
import {useContext} from 'react'
import {Modal} from 'antd'
// App.tsx
// export default () => {
// return <ModalProvider><App /><ModalProvider>
// }
export default () => {
const modalman = useContext(ModalContext)
return (
<>
<Button onClick={() => modalman.show('yourId', {yourData}}></Button>
<Modalman id="yourId">
<YourCustomComponent /> // you can get 'yourData' from 'props.data'
</Modalman>
</>
)
}
import React, { useState, useCallback } from 'react'
import _ from 'lodash'
export interface IModalContext {
modalState: any
setModalState: React.Dispatch<React.SetStateAction<{}>>
show: (id: string, data?: any) => void
hide: (id: string) => void
}
export const ModalContext = React.createContext({ modalState: {} } as IModalContext)
export const ModalProvider: React.FC<{ children: React.ReactNode }> = (props) => {
const [modalState, setModalState] = useState({})
const show = useCallback(
(id: string, data: any) => {
const newModalState = { ...modalState }
newModalState[id] = { visible: true, data }
setModalState(newModalState)
},
[modalState],
)
const hide = useCallback(
(id: string) => {
const newModalState = _.omit(modalState, id)
setModalState(newModalState)
},
[modalState],
)
return (
<ModalContext.Provider value={{ modalState, setModalState, show, hide }}>
{props.children}
</ModalContext.Provider>
)
}
import { Modal } from 'antd'
import { ModalProps } from 'antd/lib/modal'
import React, { useCallback, useContext } from 'react'
import { ModalContext } from './context'
export { ModalContext, ModalProvider } from './context'
export interface IModalManChildProps {
cancelId?: string
data?: any
}
export interface IModalmanProps {
id: string
children: React.ReactNode
}
const Modalman = React.forwardRef<any, ModalProps & IModalmanProps>((props, ref) => {
const { id } = props
const modalContext = useContext(ModalContext)
const onCancel = useCallback(() => {
modalContext.hide(id)
}, [modalContext.modalState])
return (
<Modal
ref={ref}
visible={Reflect.has(modalContext.modalState, id) && modalContext.modalState[id].visible}
destroyOnClose={true}
onCancel={onCancel}
footer={props.footer || null}
{...props}
>
{React.cloneElement(props.children as React.ReactElement, {
cancelId: id,
data: modalContext.modalState[id]?.data,
})}
</Modal>
)
})
export default Modalman
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment