javascriptreactjsroutesreact-router

Prompt with callback when user tries to exit


I have a page which in it there is a Webrtc call between users.

And i want that when a user tries to go to another page/reload page/exit browser, there will be a prompt asking him if he's sure that he wants to leave the page, and if the user presses "yes", i want there to be a callback.

In the callback(not sure if relevant) i would close the peers and disconnect everything properly so that the call will get disconnected and the user won't hear audio anymore and the other side will know the user got disconnected also.

I will be happy to get one working example as it feels to complicated for such a little thing which is weird..

Thanks.


Solution

  • Handling React's navigation events

    I think what you're looking for is the getUserConfirmation prop of BrowserRouter component.

    The function passed to the prop might look like (TypeScript example):

    const getUserConfirmation = (
        message: string ="Do you want to navigate away?",
        callback: (ok: boolean) => void
    ): void => {
        const answer = window.confirm(message);
    
        // do something depending on which button was pressed
    
        callback(answer); // allow or disallow React's navigation
    };
    

    In the place where you define your routes:

    <BrowserRouter getUserConfirmation={getUserConfirmation}>
        ... routes go here ...
    </BrowserRouter>
    

    You'll still need to use <Prompt>, though:

    <Prompt
         when={boolean}
         message="This string will be supplied in the confirmation function above as second parameter"
    />
    

    Handling browser refresh

    You might want to add a callback like this

    window.onbeforeunload = () => {
        // some non-blocking logic
    
        return true;
    };
    

    After you no longer need it, you can cleanup:

    window.onbeforeunload = null;
    

    Looking at this SO question, it doesn't seem to be possible out of the box to capture the user's response to the native confirm window in onbeforeunload.

    Probably window.onunload would be the right place to clean up your stuff as it most probably means the user has opted to leave the page.