Search code examples
javascriptreact-routerhistory.jshtml5-history

react-router v4: prevent transition with custom hook instead of Prompt


In react-router v3, I've been using router.setRouteLeaveHook to check if a form has unsaved changes, and if so return false to prevent the transition. Then I would display a custom bootstrap modal dialog with 3 buttons: Save Changes, Discard Changes, and Stay Here.

I can't use react-router v4's Prompt component to do this because it's not possible to customize the buttons shown in a browser confirm dialog. It seems like they got rid of any way to cancel the transition in favor of only allowing you to ask the user to approve the transition in a browser confirm dialog.

I tried looking in the code for Prompt but it just passes the dialog message to history, so that doesn't give me any idea how to set up a v3-style route leave hook.

Is it even possible anymore or did the react-router devs intentionally decide to remove this capability this for some reason?


Solution

  • Can use Prompt to show custom dialogue. Credit and detailed explanation here.

    Prompt requires a message prop, here we can use a custom function for a dialogue and it should return false to prevent navigation.

    const BlockingPage = () => {
      const [block, setBlock] = useState(true);
      
      const blockedNavigation = (nLocation) => {
        //nLocation gives the next location object
        
        /**
          * Your custom logic
          *
        **/
        
        //required to block navigation
        return false
      } 
    
      return(
        <div>
          <Prompt when={block} message={blockedNavigation}/>
        </div>
      )
    
    }