Manage Popups Easily In React
Learn how you can better manage modals using React Context
Introduction
If you already are frustrated enough with managing popups in React, you can definitely skip my grumbling and jump to Let’s start, and we shall build a modal manager using context
.
If you are working with React for a while, you probably thought to yourself isn’t weird having to manage the state
of a modal each time with the same isOpen
, isVisible
key words.
Especially when it is a prompt dialog such as “Are you sure?”, or a toast message saying “Action has been completed successfully”
What does these modals have to do with the current component?!
Where in the component’s render
function am I supposed to add them?!
How do I reuse them in a list? Do I need to hold in the state
the clicked item in the list?
React projects get complex enough as is. Having to manage states of modals just makes the code less readable, increases the state size of each component, and duplicates logic throughout the system.
All this repeating code also increases the system’s bundle size.
“These pretzels are making me thirsty!” — Seinfeld
In most cases you want to open a popup with some initial data, and not manipulate it’s props while it’s already open.
And when it closes you want to get its result in a callback
.
Doesn’t this feel like an API would be the best approach?
So, Why isn’t there a react-popup-manager solution out there?!
Let’s create one!
(there actually is one. so why waste time on learning it if you can just skip to using it — here it is)
Let’s Start
You probably heard by now about context
. You haven’t? So, it provides a way to pass data through the component tree without having to pass props down manually at every level (thanks react docs).
Popups are global in nature, are usually shoved to the top of the DOM
to avoid z-index
blockage. Often times you’ll want to reuse them everywhere in the system. You probably know where i’m going with this… so..
Lets code
Lets break it down:
PopupManager
A service that will be the only point of handling popups in our entire system.
Kinda straight forward. there is a list of popups
.
You open
it, and it is set to isOpen:true
. You close
it, and it is set to isOpen:false
.
The pub-sub code will be clear by the next paragraph.
PopupsWrapper
Here it will render
all the open popups in the system. it’s in the root of the application.
As you can see here, the component subscribes to the popupManagers
pub-sub by calling subscribeToPopupsChange
. And calls forceUpdate
in order to re-render when there is a change in the popups. Go back a paragraph and you’ll see callPopupsChangeEvents
is triggered in open
and in close
functions. so we can be certain the changes will get to the DOM
.onClose
will allow sending params back to caller, but more on that later…
Last step - use the context
Now some react hocus pocus.
This is a wrapper function component, that passes the popupManager
as a prop
to any component that needs to consume that service without being an immediate child.
Remember that PopupProvider
, when we created PopupContext
? So here we are using it.
If this syntax seems confusing check again the react docs here
Lets use this, awesome, yet very simple ,mini-library
Boilerplate time
Now the application is wrapped with the PopupProvider
.
Here we used withPopups
to add popupManager
as a prop
to the component
.
isOpen
and onClose
were added by the popupWrapper
.
The rest were sent using the popupManager
’s open
function.
and… Done!
This was a simple, shorter than 3 mins read, implementation.
Luckily, there is a library that does this and more.
Check it out here:
Example with and without react-popup-manager
The old way — Using state
The new way — Using react-popup-manager
I hope there will eventually be a season 4, and that I managed to convince you to use this approach.