Reputation: 280
Im trying to create a react Modal component from scratch. I would like to add the functionality of closing the modal when another one is opened.
I know the logic how to solve(i think i know), but cant implement it. My approach would be using context, where i store the current modal opened(currentModal) and if another one is opened then it would check if there is a currentModal and if so it would close it.
So far i have the modal component:
export function Modal({title, isOpen, children, onClose}){
return(
createPortal(
<trds-modal class={isOpen ? 'opened': ''} onClick={onClose}>
<trds-modal_container onClick={e => e.stopPropagation()}>
<trds-modal_header>
<h2>{title}</h2>
<Icon icon="x" onClick={onClose} />
</trds-modal_header>
<trds-modal_body>
{children}
</trds-modal_body>
</trds-modal_container>
</trds-modal>, document.body)
)
}
Upvotes: 0
Views: 53
Reputation: 280
i figured it out.
Created a context provider where i store the id of the current modal opened.
export function ModalContextProvider({children}){
const [currentModalId, setCurrentModalId] = useState(null);
return(
<modalContext.Provider value={[currentModalId, setCurrentModalId]}>
{children}
</modalContext.Provider>
)
}
then in the modal component i generate a uniqe id and set the context's currentModalId to that. And if the currentModalId changes then the modal checks if that equals to the modalId. If not, it calls the onClose function.
export function Modal({title, isOpen, children, onClose}){
const modalId = useMemo(() => generateId(), []);
const [currentModalId, setCurrentModalId] = useContext(modalContext);
useEffect(() => {
if(isOpen){
setCurrentModalId(modalId);
}
}, [isOpen, setCurrentModalId, modalId]);
useEffect(() => {
if(currentModalId !== modalId) onClose();
}, [currentModalId, modalId, onClose]);
return(
createPortal(
<trds-modal class={isOpen ? 'opened': ''} onClick={onClose}>
<trds-modal_container onClick={e => e.stopPropagation()}>
<trds-modal_header>
<h2>{title}</h2>
<Icon icon="x" onClick={onClose} />
</trds-modal_header>
<trds-modal_body>
{children}
</trds-modal_body>
</trds-modal_container>
</trds-modal>, document.body)
)
}
I hope it help you as i couldn't find an approach to this problem. (maybe its not even an existing problem :D)
Upvotes: 1