You can use usePrompt or useBlocker to detect and show a prompt before leaving to another route if they have any unsaved changes (for example in a unsaved form element).
However, in the official documentation of react router v6 the following is mentioned:
from v5 (along with usePrompt and useBlocker from the v6
betas) are not included in the current released version of v6.
I checked on Github as well, even the current version 6.2.1 doesn't support usePrompt and useBlocker.
But you can still downgrade to v5 or 6.0.0-alpha.5
the following code is working with the react router v6.0.0-alpha.5
import React, { useState, useRef, useEffect } from "react";
import {
BrowserRouter as Router,
Switch,
Route,
Link,
useHistory,
usePrompt,
useBlocker,
Routes
} from "react-router-dom";
// Sometimes you want to prevent the user from
// navigating away from a page. The most common
// use case is when they have entered some data
// into a form but haven't submitted it yet, and
// you don't want them to lose it.
export default function PreventingTransitionsExample() {
return (
<Router>
<ul>
<li>
<Link to="/">Form</Link>
</li>
<li>
<Link to="/one">One</Link>
</li>
<li>
<Link to="/two">Two</Link>
</li>
</ul>
<Routes>
<Route path="/" exact children={<BlockingForm />} />
<Route path="/one" children={<h3>One</h3>} />
<Route path="/two" children={<h3>Two</h3>} />
</Routes>
</Router>
);
}
function BlockingForm() {
let [isBlocking, setIsBlocking] = useState(false);
usePrompt(
"Hello from usePrompt -- Are you sure you want to leave?",
isBlocking
);
// useBlocker(
// () => "Hello from useBlocker -- are you sure you want to leave?",
// isBlocking
// );
return (
<form
onSubmit={event => {
event.preventDefault();
event.target.reset();
setIsBlocking(false);
}}
>
<p>
Blocking? {isBlocking ? "Yes, click a link or the back button" : "Nope"}
</p>
<p>
<input
size="50"
placeholder="type something to block transitions"
onChange={event => {
setIsBlocking(event.target.value.length > 0);
}}
/>
</p>
<p>
<button>Submit to stop blocking</button>
</p>
</form>
);
}