How to Close the React Modal
Now that we have the ability to open the Modal by simply clicking on it, we now need the ability to close it.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

We have two different ways that we're gonna want to close it. The first is if a user just simply clicks anywhere outside the Modal, that's the anticipated behavior is being able to do that. Once again React Modal does give you so much flexibility that if you wanted to create a Modal that couldn't be closed such as a Modal that had some kind of required field or something the user had to do.

It's really nice because with this prop we're gonna work through, you can actually control how a Modal is able to be closed and so that gives you a really nice set of controls that a lot of the other Modal libraries I've seen don't give you.

So that's one scenario, the other scenario is if the user clicks the Escape key, that's another very common pattern that a user would be expecting to have. So that's what we're going to implement in this guide and we're gonna see how we can pass another and a slightly different prop into the react Modal.

This process we're gonna follow in this guide is nearly identical to the process we followed in the last guide. So hopefully it will start to become a little bit more familiar because it's something you're gonna be doing quite a bit. So let's switch to Visual Studio Code and the very first thing I'm going to do here is pass in another prop.

Now if you're curious on how I'm able to know what these props are, it's all in the documentation if you go to the react-modal library, all of these lists of props, all of the options, everything like that is all there, many times with examples.

So when I was originally researching this for adding my very first react modal, I simply went through the examples and saw the list of props with their descriptions and that's how I knew how to do it. So I'm not making these props out of thin air or anything like that, this is all coming straight from the documentation which is why it's so critical to read that.

So the prop name here is called onRequestClose, you may also notice we have some helpful auto-complete here with the Visual Studio code editor, what it does is it's going into that react modal library and it's pulling out all of the available props.

So we have that with auto-complete so I say onRequestClose and then what I want to pass in here is not a piece of state like we did this time where it was modalIsOpen. The difference between these two props is that isOpen expects to get either a true or false value onRequestClose is different, it expects to run a function.

So before we even tie it in with the blog component, let's walk through what that actually looks like. So we're gonna pass in a function here so I'm gonna just use a fat arrow function. So I'll start with empty parenthesis, the arrow syntax, and then from here let's just put this on a different line and I'm just gonna say console.log.

So I don't even wanna change state, I don't even wanna close the Modal yet, for right now let's just test to see if this works. So I'm gonna say testing modal close, hit save and so now let's actually test this out in the browser.

render() {
  return (
    <ReactModal
      onRequestClose={() => {
        console.log("testing modal close");
      }}
      isOpen={this.props.modalIsOpen}
    >
      <h1>I'm in a modal!</h1>
    </ReactModal>

So if you open up the JavaScript console and then you click on open Modal and don't worry about this warning right here, we'll take care of that later, let's clear out the terminal.

large

If I click outside of the Modal, you can see that testing Modal close fires.

large

The reason why that works is because this specific prop this onRequestClose prop is already built in with the knowledge of if a user clicks outside the Modal area, then that probably means I wanna close it and so we're going to fire this function and so that's exactly what it's doing.

Now if I hit refresh again and let's open the Modal again, if I hit escape, you'll see it says testing modal close.

large

So it covers all of our use cases, just with this one simple command and we're simply passing a function in and so all we're saying with this onRequestClose is that whenever a user clicks outside the Modal or when they hit escape, I want you to do and run any code inside of this function, that's what it's saying.

So as you can imagine what this means for us and what we wanna do is that if we pass our own function directly into this prop right here it will be triggered and you can probably already think about what you wanna pass in. You wanna pass in a function as a prop from the blog component here that will turn our state off, so instead of the Modal being open we want the Modal to be closed. So now that we have that, let's actually build it out.

So I'm going to call the prop, so I'll say this.props and let's just call it handleModalClose and because this is an actual function that we want to fire that's a reason why we have to call it with parenthesis whereas whenever we're passing in a method that's simply a callback function, we don't have the parenthesis in there but whenever you call a prop as a function and it's inside of an anonymous function that's when you're gonna want to put the parenthesis in there.

And I know if you're a new developer that may seem like a kind of a fuzzy concept you may not know when you use one versus the other. Just to know that the reason why we put this anonymous function inside of here is because we want to wrap up that process so that it only is going to run when we want it to. Which in this case is whenever the user's clicking outside the Modal or hitting escape.

blog-modal.js

render() {
  return (
    <ReactModal
      onRequestClose={() => {
        this.props.handleModalClose();
      }}
      isOpen={this.props.modalIsOpen}
    >
      <h1>I'm in a modal!</h1>
    </ReactModal>

So I'm gonna hit save there on that file and now let's go and make the changes necessary in the blog component. I'm going to create a new function and tie it in with the component. So I'll say this. and let's just call this handleModalClose and tie it to this.handleModalClose.bind to this and following the same pattern as before, we'll create this method definition it doesn't take any arguments in and we're gonna call this.setState and take that blogModalIsOpen set a state and we're gonna change it to false.

blog.js

  this.getBlogItems = this.getBlogItems.bind(this);
  this.onScroll = this.onScroll.bind(this);
  window.addEventListener("scroll", this.onScroll, false);
  this.handleNewBlogClick = this.handleNewBlogClick.bind(this);
  this.handleModalClose = this.handleModalClose.bind(this);
}

handleModalClose() {
  this.setState({
    blogModalIsOpen: false
  });
}

handleNewBlogClick() {
  this.setState({
    blogModalIsOpen: true
  });
}

Hit save there and then from that point all we have to do is come down to our JSX code and add another prop here and I'm gonna put this on a different line just to make it a little easier to read. So I'll say handleModalClose is equal to what we're passing in this.handleModalClose.

return (
  <div className="blog-container">
    <BlogModal
      handleModalClose={this.handleModalClose}
      modalIsOpen={this.state.blogModalIsOpen}
    />

So hit save here and this should give us everything that we need. So let's go check this out in the browser, I'm gonna close the terminal, hit refresh and if you click on open Modal you'll see that it pops up if I click outside, the Modal is closed, if I open it up again and then click the escape key it's working.

So this is doing exactly what we want it to do, we now have the ability to open and close the Modal using all of the standard user experience type of behavior that you'd expect from a Modal.

So great job if you went through that you now have a truly fully functional Modal and now that we have that let's start adding a few styles to it.

Resources