DEV Community

Shubham
Shubham

Posted on • Originally published at shubhamverma.dev

How to create a custom dialog in React to show before user leave

Custom dialog

Hello there, Today I am going to show a little trick in React that how you can create your custom own dialog to ask the user before they switch route(instead of native one) when some value required some action (for ex: to save that form, to do some action based on that change)

How it comes?

I was assigned one module where I have to prompt custom dialog when user have something changed into there form and they try to leave the site without saving those changes.

My findings

To be honest, Initially, I thought it might be easy to do as it is a simple dialog and just has to maintain some state to show/hide prompt. But the issue came when I have to track route changes also. After searching google I came to know about this but since we had a requirement to show the custom dialog. Since onBeforeUnload won't allow customizing its dialog(you can only change text string). After exploring not exact solution I have found that some packages are doing this.
But we(my team) don't want to use any third-party library for that. So I got the chance to research that.

Solution

After exploring more on google and StackOverflow came to know about react-router provide history prop which can be utilized for that requirement. Then I started trying implementing it after going through their docs. And it was easy as I thought.
So basically you need to follow these steps to do that:

  • Create your dialog component
  • From wherever you want to block your route. Use history.block on the component mount (This will block your navigation)
  componentDidMount(){
    const {history} = this.props;
    this.unblock = history.block(tx => {
      // Navigation was blocked! Let's show a confirmation dialog
      // so the user can decide if they actually want to navigate
      // away and discard changes they've made in the current page.
      this.url = tx.location.pathname;
    });
  }
Enter fullscreen mode Exit fullscreen mode
  • Since history.block gives you a callback that means you can unblock navigation by executing that
    mySomeRandomFunction(){
      const {history} = this.props;
      this.unblock(); //If condition is satisfied
    }
Enter fullscreen mode Exit fullscreen mode
  • So once criteria are satisfied unblock that route. That's it you have to do only that

Last but not the least (DEMO)

Edit custom-modal-route-block

Caveat

According to history documentation:

history.block will call your callback for all in-page navigation attempts, but
for navigation that reloads the page (e.g. the refresh button or a link that
doesn't use history.push) it registers a beforeunload
handler

to prevent the navigation. In modern browsers you are not able to customize this
dialog

Keep above thing in mind i.e it wont work if page is reload it only work if you try to change some action in page

Top comments (0)