How to create a custom dialog in React to show before user leave
Tags: react, javascript, hooks
Published: 2021-01-01 12:06:37

![Custom dialog](https://dev-to-uploads.s3.amazonaws.com/i/7vbez1sxvkl1vvz3ur8e.png)

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](https://stackoverflow.com/a/276739/11511722) 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](https://reactrouter.com/web/api/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)

  ```jsx
  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;
    });
  }
  ```

- Since `history.block` gives you a callback that means you can unblock navigation by executing that

  ```jsx
    mySomeRandomFunction(){
      const {history} = this.props;
      this.unblock(); //If condition is satisfied
    }
  ```

- 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](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/custom-modal-route-block-bmqci?fontsize=14&hidenavigation=1&theme=dark&view=preview)




### 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](https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event)
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`