React Portal: Building A Modal

Joe C Gomez
3 min readMar 15, 2021

--

GitHub: https://github.com/JoeG21/medium-ex/tree/master/react-modal/src

Almost all applications today uses some sort of pop-up whenever you click a button or anything of that matter. Modals are great features that looks simply to build but can be tricky to tackle when given the task. So I hope I can help someone who is struggling with this feature!

As you can see with our example, whenever we click on that button it’s going to give us a modal that covers the whole screen. Even the our header will be cover as well, it is important. Because the biggest problem people face is covering other styling.

First, our boiler plate code.

const App = () => {  return (    <div className="App">      <h1 className='header'> 👋 The Modal Will Cover Me Too! </h1>      <button> Open Me! </button>    </div>  );}

Now let’s add some state for whenever we click our button to open and close our modal, we are just going to make it a boolean value of false. If you don’t know useState, you can check out my blog on it!

https://devjoe.medium.com/implementing-react-hooks-usestate-53e565669439

Add a onClick event listener to our button and call our “setOpen” function to update our state to be “true”.

import { useState } from 'react'const App = () => {  const [open, setOpen] = useState(false)  return (    <div className="App">      <h1 className='header'> 👋 The Modal Will Cover Me Too! </h1>      <button onClick={() => setOpen(true)}> Open Me! </button>    </div>  );}

Define our Modal component and pass down our “open” state.

import { useState } from 'react'import Modal from './Modal.js'const App = () => {  const [open, setOpen] = useState(false)  return (    <div className="App">      <h1 className='header'> 👋 The Modal Will Cover Me Too! </h1>      <button onClick={() => setOpen(true)}> Open Me! </button>      <Modal open={open} />    </div>  );}

Let’s move over to our Modal component and add some logic. First, we need to return our “open” state to be null or else it’s going to always open. Second, let’s add a callback function, “handleClose”, in order for us to close our modal when opened. Third, add our Div tags and give them classnames to select them later on!

import React from 'react'const Modal = (props) => {  if (!props.open) return null  return (    <div className='overlay'>      <div className='modal'>        <p> Hello World! </p>        <button onClick={props.handleClose} > Close Me! </button>      </div>    </div>  )}

Move back to our App component, and add our callback function that we defined in our Modal component.

import { useState } from 'react'import Modal from './Modal.js'const App = () => {  const [open, setOpen] = useState(false)  const handleClose = () => {    setOpen(false)  }  return (    <div className="App">      <h1 className='header'> 👋 The Modal Will Cover Me Too! </h1>      <button onClick={() => setOpen(true)}> Open Me! </button>      <Modal open={open} handleClose={handleClose} />    </div>  );}

Now that we have all of our logic working, let’s add some styling to our modal in our CSS file. Select our Divs by classnames that we gave in our Modal component and follow this format in order to center everything!

#App.css.overlay {
position: fixed;
top: 0; left: 0; right: 0; bottom: 0; background-color: rgb(0, 0, 0, .5); z-index: 1000;
}
.modal {
color: white;
padding: 5vw; font-size: 3vw; background-color: #b18611; border-radius: 8px; border: 2px solid white; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 1000; display: flex; flex-direction: column;
}

At this point you would think we’re finish, but we are not! Now in order to make this truly overlay everything in our screen, we to make portals.

First, let’s go to our index.html file and add another Div tag right underneath our “root” Div with an id of “portal”.

<div id="root"></div><div id='portal'></div>

Let’s go back to our Modal component and target our “portal” div.

import React from 'react'import ReactDOM from 'react-dom'const Modal = (props) => {
if (!props.open) return null
return ReactDOM.createPortal(
<div className='overlay'>
<div className='modal'> <p> Hello World! </p> <button onClick={props.handleClose} > Close Me! </button> </div> </div>,
document.getElementById('portal')

)
}
export default Modal

Now we are done! Thank you, check out my GitHub for the code!

GitHub: https://github.com/JoeG21/medium-ex/tree/master/react-modal/src

--

--

Joe C Gomez
Joe C Gomez

Written by Joe C Gomez

Find some time to do something! 🧠 Flatiron Alumni 🏛

No responses yet