When I was a beginner developer, I struggled with opening and closing modals, the UI itself was no issue, but managing the state of the application modals was a trouble, if you feel or ever felt the same, go through this simple and short tutorial, I will give you a guide on how to make it better.
Requirements
SPA (react, vue, ...) or SSR (next, nuxt, ...)
Application state management tool (redux, ...)
Modal design or a ready one like MUI's modals
For this tutorial, I'm going to use react, redux and MUI's modal
Enough with the intro, let's start some code
I suppose you will have a layout that wraps your code, assume this is the content of it
<div>
<Navbar />
{children} // these are the actual page content
<Footer />
</div>
To have a central modal to be managed from everywhere in the code you should have a central state, in my case it's redux
ModalState {
isOpened: boolean;
current: "auth-modal" | "checkout-modal" | "confirm-modal";
args: any;
}
isOpened is a boolean to check if the modal is currently opened
ModalType is a string that identifies the current modal to be rendered
args is any kind of arguments you want to send to the current modal
Inside the modal state slice
openModalAction: (state, action) => {
const { current, args } = action.payload;
return {
isOpened: true,
current,
args
}
},
closeModalAction: (state, action) => {
return {
...state,
isOpened: false,
args: []
}
}
openModalAction sets the current modal and sends the required props to that modal through the args parameter
closeModalAction closes the modal opened no matter any
Going back to the layout that is wrapping the whole app you can add one more component
<div>
<Navbar />
{children} // these are the actual page content
<Footer />
<CentralModalRenderer />
</div>
for the CentralModalRenderer component, it can be like the following
const dispatch = useDispatch();
const { current, isOpened, args } = useSelector((state) => state.modal)
function renderCurrentComponent() {
switch (current) {
case "auth-modal":
return (<AuthModal {...args} />)
case "checkout-modal":
return (<CheckoutModal {...args} />)
default:
return null
}
}
const handleClose = () => {
dispatch(closeModalAction())
}
return (
isOpened ? (
<Modal
open={isOpened}
handleClose={handleClose}
>
{renderCurrentComponent()}
<Modal/>
) : null
)
Modal is MUI's modal, that requires two props, boolean to for the modal to be opened or not, and on close handler
isOpened whenever true will open the modal state
renderCurrentComponent is a function to check which is the current value in the modal state and renders the modal component created that matches
Notice that the args are always sent to the component, so how to open it, easy
<button
onClick={() => dispatch(openModal({current:"auth-modal", args:{message:"Are you sure you want to leave?"}}))}
>
open modal
</button>
I hope this was enough to start your own central modal, the same idea can be used to implement a central notification system, or a central management state for UI, all over your code and components
Top comments (0)