React Modal – The easy way to show a modal without Redux

Creating a modal box (or popup) is not difficult, but also not easy. I spent 2-3 days finding a solution to build a modal in my React project. As my background is from jQuery and pure JavaScript, I was not aware of the possibility for ReactDOM to build a modal. In this post, I will go through the process of building a modal without JavaScript, and how it is solved by “react-modal” component.

How to create a modal without JavaScript

It is quite simple to build a modal without adding any library into your project. Although it comes with a little constraint that the modal’s HTML element needs to be in the outer level of DOM (jQuery library do that for us). The HTML should look like the code in an image below:

The most simplest way to build a modal

Note that the “modal” element can be placed inside or outside the “wrapper” element, and the CSS of the modal can be styled in different ways to accomplish the same result.

If you want to learn more, you can check out the example code of building a modal in CSS by petebot:

Problems with creating a modal with React

React is just a JavaScript view library. The resulting code from React will be in HTML and CSS. Thus, we can use the same idea as the modal in pure HTML & CSS.

However, I got struggled with creating a modal with React, because most of the time React components are nesting in another components. e.g.

<App>
  <Header />
  <Content>
    <Box>
      <Modal />
    </Box>
  <Footer />
</App>

In this example, I would like to call a modal from <Box> component which is inside <Content>. But the problem now is that the placement of <Modal /> in DOM is incorrect. It should be placed in the same level as <Content> or <App> in order to show the modal and modal overlay correctly.

One way I could think of at the time was adding Modal element in the <App>, then open and close the modal by storing variable in Redux store e.g.

<App>
  <Header />
  <Content>
    <Box />
  <Footer />
  <Modal />
</App>

This is the recommended way by Dan Abramov. While it is indeed more organized, I felt this method is unnecessary for creating a simple modal. I have to create at least 5 files (components, action, reducer).

Solution: React-modal

One thing I did not know about React is that it can actually “warp” component to other places in the DOM. This solution is done using libraries such as react-portal and react-warp-portal. The idea is interesting, but I would need to implement a modal component to work with them.

I would like to keep the code as simple as possible since the project might be handed to other people to continue working based on my code (this is the project for winter scholarship at my uni). At the end, the solution I used in my React project is react-modal. I can write <Modal /> in any level of the components, and the library will automatically “warp” the modal to the outer level of DOM.

It is noteworthy about how react-modal did it. I digged in its code and found the method called ReactDOM.unstable_renderSubtreeIntoContainer. This method allowed us to render React component in other places in the DOM. I guess react-portal and react-warp-portal libraries might use the method as well.

The code from react-modal is like this:

renderPortal = props => {
  this.portal = renderSubtreeIntoContainer(this, (
    <ModalPortal defaultStyles={Modal.defaultStyles} {...props} />
  ), this.node);
}

This is the end of my long journey in finding a way to show a modal in React. If you want to learn more about this topic, I came across this article from David Gilbertson which nicely explained all the solutions available using React.

I would like to thanks people at ReactJS Developer Thailand group who helped me came up with the solution: Here and Here


Also published on Medium.

Leave a Reply

Your email address will not be published. Required fields are marked *