DEV Community

Nobu
Nobu

Posted on

How to display a confirmation dialog asking whether to discard the changes with react-router-dom v6

Expected result

After the user entered values in a form,
・display a confirmation dialog when attempting to reload a page.
Screenshot 2023-10-29 at 13.34.06.png
・display a confirmation dialog when attempting to transition to another page.
Screenshot 2023-10-29 at 13.34.17.png

Issue

react-router-dom v6 removes useBlocker, which is necessary to prevent page exits, and requires another implementation.

Reference
https://stackoverflow.com/questions/70617041/react-router-v6-doesnt-support-prompt-or-useprompt

Library I used

react-router-prompt
https://github.com/sshyam-gupta/react-router-prompt/tree/main

Actually, I copied and used only the three necessary files in this library.
https://github.com/sshyam-gupta/react-router-prompt/blob/main/src/hooks/use-confirm.ts
https://github.com/sshyam-gupta/react-router-prompt/blob/main/src/hooks/use-prompt.ts
https://github.com/sshyam-gupta/react-router-prompt/blob/main/src/index.tsx

The reason was that it was an unofficial react-router library and I didn't know if it would continue to be updated in the future.
I thought it would be usable just by porting the above three files, so I didn't use the library as it is this time. Instead, I ported the code and used it.

This is a repository I coded.
https://github.com/nobu0605/react-router-prompt

Of course, you can also use the library as it is.

How to use

Whether you use a library or create your own, you call ReactRouterPrompt as shown below and wrap the dialog etc.
Pass the change detection flag to when props.

import ReactRouterPrompt from "./ReactRouterPrompt";
import Button from "@mui/material/Button";
import Dialog from "@mui/material/Dialog";
import DialogActions from "@mui/material/DialogActions";
import DialogContent from "@mui/material/DialogContent";
import DialogContentText from "@mui/material/DialogContentText";
import DialogTitle from "@mui/material/DialogTitle";

type Props = {
  when: boolean;
};

export function UnsavedConfirmDialog({ when }: Props) {
  return (
    <ReactRouterPrompt when={when}>
      {({ isActive, onConfirm, onCancel }) =>
        isActive && (
          <Dialog open={isActive}>
            <DialogTitle>Do you really want to leave?</DialogTitle>
            <DialogContent>
              <DialogContentText>
                Your changes will not be saved.
              </DialogContentText>
            </DialogContent>
            <DialogActions>
              <Button onClick={onCancel}>cancell</Button>
              <Button onClick={onConfirm} autoFocus>
                ok
              </Button>
            </DialogActions>
          </Dialog>
        )
      }
    </ReactRouterPrompt>
  );
}


Enter fullscreen mode Exit fullscreen mode

Complement

I used the beforeunload event to display a confirmation dialog when trying to reload a page, but it seems that custom messages or self-made dialogs cannot be displayed.
The default dialog for each browser will be displayed.
https://stackoverflow.com/questions/38879742/is-it-possible-to-display-a-custom-message-in-the-beforeunload-popup

Top comments (0)