Want to open modals from any place in your code? this article is for you!
Tags: javascript, webdev, modal, tutorial
Published: 2022-11-05 12:47:13

## 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