useNavigation
This hook tells you everything you need to know about a page navigation to build pending navigation indicators and optimistic UI on data mutations. Things like:
import { useNavigation } from "react-router-dom";
function SomeComponent() {
const navigation = useNavigation();
navigation.state;
navigation.location;
navigation.formData;
navigation.json;
navigation.text;
navigation.formAction;
navigation.formMethod;
}
useNavigation().formMethod
field is lowercase without the future.v7_normalizeFormMethod
Future Flag. This is being normalized to uppercase to align with the fetch()
behavior in v7, so please upgrade your React Router v6 applications to adopt the uppercase HTTP methods.
navigation.state
Normal navigations and GET form submissions transition through these states:
idle → loading → idle
Form submissions with POST, PUT, PATCH, or DELETE transition through these states:
idle → submitting → loading → idle
Here's a simple submit button that changes its text when the navigation state is changing:
function SubmitButton() {
const navigation = useNavigation();
const text =
navigation.state === "submitting"
? "Saving..."
: navigation.state === "loading"
? "Saved!"
: "Go";
return <button type="submit">{text}</button>;
}
While navigation.state
provides the high-level state of the active navigation, you can deduce more granular information by combining it with other navigation
aspects:
// Is this just a normal load?
let isNormalLoad =
navigation.state === "loading" &&
navigation.formData == null;
// Are we reloading after an action?
let isReloading =
navigation.state === "loading" &&
navigation.formData != null &&
navigation.formAction === navigation.location.pathname;
// Are we redirecting after an action?
let isRedirecting =
navigation.state === "loading" &&
navigation.formData != null &&
navigation.formAction !== navigation.location.pathname;
navigation.formData
Any POST, PUT, PATCH, or DELETE navigation that started from a <Form>
or useSubmit
will have your form's submission data attached to it. This is primarily useful to build "Optimistic UI" with the submission.formData
FormData
object.
In the case of a GET form submission, formData
will be empty and the data will be reflected in navigation.location.search
.
navigation.json
Any POST, PUT, PATCH, or DELETE navigation that started from a useSubmit(payload, { encType: "application/json" })
will have your JSON value available in navigation.json
.
navigation.text
Any POST, PUT, PATCH, or DELETE navigation that started from a useSubmit(payload, { encType: "text/plain" })
will have your text value available in navigation.text
.
navigation.location
This tells you what the next location is going to be.
Note that this link will not appear "pending" if a form is being submitted to the URL the link points to, because we only do this for "loading" states. The form will contain the pending UI for when the state is "submitting", once the action is complete, then the link will go pending.