React Router Cheatsheet
Migration and Pitfalls
Use this React Router reference while you build software engineering projects, review code, or refresh the syntax you reach for most.
v5 to v6/v7 Migration
| v5 | v6 / v7 |
|---|---|
<Switch> | <Routes> |
component={X} | element={<X />} |
render={() => …} | element={…} |
| Exact by default off | Exact by default on, use * or nesting for prefixes |
exact prop | Removed, paths match exactly unless nested |
| First match wins | Best match wins (ranked) |
useHistory() | useNavigate() |
history.push(p) | navigate(p) |
history.replace(p) | navigate(p, { replace: true }) |
history.goBack() | navigate(-1) |
<Redirect to> | <Navigate to replace> |
useRouteMatch() | useMatch() |
props.match.params | useParams() |
withRouter | Hooks, or wrap it yourself |
Nested <Route> anywhere | Nest in the route config, render <Outlet /> |
react-router-config | Built in via route objects |
v6 to v7 Migration
| v6 | v7 |
|---|---|
react-router-dom | react-router |
json({ … }) | Return a plain object, or data() |
defer({ … }) | Return bare promises |
useTransition (router) | useNavigation (renamed back in v6.4) |
<Remix*> components | The same names in react-router |
@remix-run/* packages | react-router and @react-router/* |
npx codemod react-router/2/upgrade-router # community codemod for the import move
Common Mistakes
| Mistake | Fix |
|---|---|
Using data APIs under <BrowserRouter> | Use createBrowserRouter + RouterProvider |
| Nested routes render nothing | The parent forgot <Outlet /> |
Every NavLink looks active | Add end to the / link |
useNavigate in an effect to redirect | Use a loader redirect() or <Navigate> |
Fetching in useEffect per component | Move it to a loader, kill the waterfall |
| Relative link goes somewhere odd | Check relative="route" vs "path" |
Params are "42" not 42 | Params are always strings, convert and validate |
| Search filter spams history | setSearchParams(next, { replace: true }) |
| No error boundary | Add errorElement on the root route |
Redirecting to a raw ?next= value | Validate it is a same-origin path |
Basename included in to | Leave it out, the router adds it |
| 404 page returns HTTP 200 | Throw a Response with status: 404 |