| 1 | ---
|
| 2 | title: Navigating
|
| 3 | order: 6
|
| 4 | ---
|
| 5 |
|
| 6 | # Navigating
|
| 7 |
|
| 8 | [MODES: framework]
|
| 9 |
|
| 10 | ## Introduction
|
| 11 |
|
| 12 | Users navigate your application with `<Link>`, `<NavLink>`, `<Form>`, `redirect`, and `useNavigate`.
|
| 13 |
|
| 14 | ## NavLink
|
| 15 |
|
| 16 | This component is for navigation links that need to render active and pending states.
|
| 17 |
|
| 18 | ```tsx
|
| 19 | import { NavLink } from "react-router";
|
| 20 |
|
| 21 | export function MyAppNav() {
|
| 22 | return (
|
| 23 | <nav>
|
| 24 | <NavLink to="/" end>
|
| 25 | Home
|
| 26 | </NavLink>
|
| 27 | <NavLink to="/trending" end>
|
| 28 | Trending Concerts
|
| 29 | </NavLink>
|
| 30 | <NavLink to="/concerts">All Concerts</NavLink>
|
| 31 | <NavLink to="/account">Account</NavLink>
|
| 32 | </nav>
|
| 33 | );
|
| 34 | }
|
| 35 | ```
|
| 36 |
|
| 37 | `NavLink` renders default class names for different states for easy styling with CSS:
|
| 38 |
|
| 39 | ```css
|
| 40 | a.active {
|
| 41 | color: red;
|
| 42 | }
|
| 43 |
|
| 44 | a.pending {
|
| 45 | animate: pulse 1s infinite;
|
| 46 | }
|
| 47 |
|
| 48 | a.transitioning {
|
| 49 | /* css transition is running */
|
| 50 | }
|
| 51 | ```
|
| 52 |
|
| 53 | It also has callback props on `className`, `style`, and `children` with the states for inline styling or conditional rendering:
|
| 54 |
|
| 55 | ```tsx
|
| 56 | // className
|
| 57 | <NavLink
|
| 58 | to="/messages"
|
| 59 | className={({ isActive, isPending, isTransitioning }) =>
|
| 60 | [
|
| 61 | isPending ? "pending" : "",
|
| 62 | isActive ? "active" : "",
|
| 63 | isTransitioning ? "transitioning" : "",
|
| 64 | ].join(" ")
|
| 65 | }
|
| 66 | >
|
| 67 | Messages
|
| 68 | </NavLink>
|
| 69 | ```
|
| 70 |
|
| 71 | ```tsx
|
| 72 | // style
|
| 73 | <NavLink
|
| 74 | to="/messages"
|
| 75 | style={({ isActive, isPending, isTransitioning }) => {
|
| 76 | return {
|
| 77 | fontWeight: isActive ? "bold" : "",
|
| 78 | color: isPending ? "red" : "black",
|
| 79 | viewTransitionName: isTransitioning ? "slide" : "",
|
| 80 | };
|
| 81 | }}
|
| 82 | >
|
| 83 | Messages
|
| 84 | </NavLink>
|
| 85 | ```
|
| 86 |
|
| 87 | ```tsx
|
| 88 | // children
|
| 89 | <NavLink to="/tasks">
|
| 90 | {({ isActive, isPending, isTransitioning }) => (
|
| 91 | <span className={isActive ? "active" : ""}>Tasks</span>
|
| 92 | )}
|
| 93 | </NavLink>
|
| 94 | ```
|
| 95 |
|
| 96 | ## Link
|
| 97 |
|
| 98 | Use `<Link>` when the link doesn't need active styling:
|
| 99 |
|
| 100 | ```tsx
|
| 101 | import { Link } from "react-router";
|
| 102 |
|
| 103 | export function LoggedOutMessage() {
|
| 104 | return (
|
| 105 | <p>
|
| 106 | You've been logged out.{" "}
|
| 107 | <Link to="/login">Login again</Link>
|
| 108 | </p>
|
| 109 | );
|
| 110 | }
|
| 111 | ```
|
| 112 |
|
| 113 | ## Form
|
| 114 |
|
| 115 | The form component can be used to navigate with `URLSearchParams` provided by the user.
|
| 116 |
|
| 117 | ```tsx
|
| 118 | <Form action="/search">
|
| 119 | <input type="text" name="q" />
|
| 120 | </Form>
|
| 121 | ```
|
| 122 |
|
| 123 | If the user enters "journey" into the input and submits it, they will navigate to:
|
| 124 |
|
| 125 | ```
|
| 126 | /search?q=journey
|
| 127 | ```
|
| 128 |
|
| 129 | Forms with `<Form method="post" />` will also navigate to the action prop but will submit the data as `FormData` instead of `URLSearchParams`. However, it is more common to `useFetcher()` to POST form data. See [Using Fetchers](../../how-to/fetchers).
|
| 130 |
|
| 131 | ## redirect
|
| 132 |
|
| 133 | Inside of route loaders and actions, you can return a `redirect` to another URL.
|
| 134 |
|
| 135 | ```tsx
|
| 136 | import { redirect } from "react-router";
|
| 137 |
|
| 138 | export async function loader({ request }) {
|
| 139 | let user = await getUser(request);
|
| 140 | if (!user) {
|
| 141 | return redirect("/login");
|
| 142 | }
|
| 143 | return { userName: user.name };
|
| 144 | }
|
| 145 | ```
|
| 146 |
|
| 147 | It is common to redirect to a new record after it has been created:
|
| 148 |
|
| 149 | ```tsx
|
| 150 | import { redirect } from "react-router";
|
| 151 |
|
| 152 | export async function action({ request }) {
|
| 153 | let formData = await request.formData();
|
| 154 | let project = await createProject(formData);
|
| 155 | return redirect(`/projects/${project.id}`);
|
| 156 | }
|
| 157 | ```
|
| 158 |
|
| 159 | ## useNavigate
|
| 160 |
|
| 161 | This hook allows the programmer to navigate the user to a new page without the user interacting. Usage of this hook should be uncommon. It's recommended to use the other APIs in this guide when possible.
|
| 162 |
|
| 163 | Reserve usage of `useNavigate` to situations where the user is _not_ interacting but you need to navigate, for example:
|
| 164 |
|
| 165 | - Logging them out after inactivity
|
| 166 | - Timed UIs like quizzes, etc.
|
| 167 |
|
| 168 | ```tsx
|
| 169 | import { useNavigate } from "react-router";
|
| 170 |
|
| 171 | export function useLogoutAfterInactivity() {
|
| 172 | let navigate = useNavigate();
|
| 173 |
|
| 174 | useFakeInactivityHook(() => {
|
| 175 | navigate("/logout");
|
| 176 | });
|
| 177 | }
|
| 178 | ```
|
| 179 |
|
| 180 | ---
|
| 181 |
|
| 182 | Next: [Pending UI](./pending-ui)
|