React Router v6 is one of the biggest rewrites in the router’s history. It’s smaller, faster, more powerful, and built for the modern React world. If you're upgrading from v5 or starting a new project, this guide gives you a complete, practical overview of what’s changed — with side-by-side v5 vs v6 code examples for every major concept.
At the end, we’ll also preview the new Data APIs introduced in React Router 6.4+, which fully change how routing + data loading works. We’ll explore those in the next blog.
1. Smarter Route Matching (No More exact or Ordering)
React Router v6 introduces a ranking-based matching algorithm, eliminating the need for exact or manually ordering routes.
✅ Improvements
- No more
exact - No strict dependency on order
- Most specific route always wins
- Static paths outrank dynamic paths
v5 Example (ordering + exact required)
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/users" component={Users} />
<Route path="/users/:id" component={UserDetails} />
</Switch>
v6 Example (ranking-based matching)
<Routes>
<Route path="/" element={<Home />} />
<Route path="/users" element={<Users />} />
<Route path="/users/:id" element={<UserDetails />} />
</Routes>
2. <Switch> → <Routes>
<Routes> replaces <Switch> and uses the new ranking algorithm to pick the best match.
v5
<Switch>
<Route path="/about" component={About} />
<Route path="/" component={Home} />
</Switch>
v6
<Routes>
<Route path="/about" element={<About />} />
<Route path="/" element={<Home />} />
</Routes>
3. Route API Changes (component, render, children → element)
This is one of the biggest differences between v5 and v6.
React Router v5 offered three different ways to render components:
component, render, and function-as-children.
React Router v6 simplifies all of this to just one:
element={<Component />}.
v5: Three Rendering Options
1) component prop
<Route path="/about" component={About} />
- Must be a component reference
- Remounts on route change
2) render prop
<Route
path="/profile"
render={(props) => <Profile {...props} mode="dark" />}
/>
- Lets you pass custom props
- Creates a new element on every render
3) Function-as-children
<Route path="/settings">
{(props) => <Settings {...props} />}
</Route>
- Runs even when the route doesn't match
- Common source of bugs
v6: One Clean Way → element
<Route path="/about" element={<About />} />
<Route path="/profile" element={<Profile mode="dark" />} />
Why this is better?
- Predictable lifecycle
- Easy to pass props
- Cleaner API
- Component trees behave naturally
4. Smaller Bundle Size (Up to ~60% smaller)
React Router v6 is a complete rewrite with better tree-shaking and modern architecture.
Many apps see bundle size reductions of 50–60%.
Nothing to change — just enjoy the faster loads 🚀
5. Config-Based Routing With useRoutes() (No More react-router-config)
v6 has built-in support for object-based route definitions.
v5
import { renderRoutes } from "react-router-config";
const routes = [
{ path: "/", component: Home },
{ path: "/users/:id", component: UserDetails }
];
renderRoutes(routes);
v6
const routes = [
{ path: "/", element: <Home /> },
{ path: "users/:id", element: <UserDetails /> }
];
function App() {
return useRoutes(routes);
}
Cleaner + native + perfect for dynamic routing.
6. Navigation: useHistory → useNavigate
useNavigate() replaces useHistory() and handles all navigation cases.
v5 Navigation
const history = useHistory();
history.push("/home");
history.goBack();
history.goForward();
history.go(2);
v6 Navigation
const navigate = useNavigate();
navigate("/home");
navigate(-1); // goBack
navigate(1); // goForward
navigate(2); // go(2)
One function. All navigation.
7. Active Nav Styling Updated
activeClassName and activeStyle are removed in v6.
v5
<NavLink
to="/"
activeClassName="active"
activeStyle={{ color: "red" }}
>
Home
</NavLink>
v6
<NavLink
to="/"
className={({ isActive }) => isActive ? "active" : ""}
style={({ isActive }) => ({
color: isActive ? "red" : "black",
})}
>
Home
</NavLink>
More control + more flexibility.
8. Redirect → Navigate
v5
<Redirect to="/login" />
v6
<Navigate to="/login" replace />
9. Nested Routing + <Outlet>
Nested routing is dramatically improved in v6.
v5 (manual, repetitive paths)
<Switch>
<Route path="/dashboard" component={Dashboard} />
</Switch>
// Dashboard.js
<Switch>
<Route path="/dashboard/settings" component={Settings} />
</Switch>
You had to repeat /dashboard for every nested route.
v6 (clean, declarative)
<Routes>
<Route path="dashboard" element={<Dashboard />}>
<Route index element={<Overview />} />
<Route path="settings" element={<Settings />} />
</Route>
</Routes>
Inside Dashboard:
<Outlet />
Beautiful routing ✨
10. Relative Routing by Default
v5
<Link to="/dashboard/settings">Settings</Link>
v6
<Link to="settings">Settings</Link>
Automatically resolves relative to the parent route.
11. Removed APIs (Hook-Based Modern Router)
React Router v6 removes:
withRouter()Prompt-
activeClassName/activeStyle -
component,render, and function-children in<Route> - Implicit nesting behavior
The API is smaller, simpler, and easier to understand.
12. Index Routes
Default child routes are now a first-class concept.
v5 Equivalent
<Route exact path="/dashboard" component={Overview} />
v6
<Route path="dashboard" element={<Dashboard />}>
<Route index element={<Overview />} />
</Route>
13. Final Section: React Router’s New Data APIs (Preview Only)
React Router 6.4+ introduced Data APIs, which completely redefine how React apps handle:
- Data loading
- Data mutations
- Forms
- Navigation side effects
- Error boundaries
- Background fetches
- Deferred loading
Here’s a small teaser:
const router = createBrowserRouter([
{
path: "/users",
loader: async () => {
return fetch("/api/users");
},
element: <Users />
}
]);
These APIs are powerful enough to replace a lot of manual fetching and state management.
Next Blog: Deep Dive into React Router’s Data APIs
In the next article, we’ll explore:
loaderactionuseLoaderDatauseActionDatauseFetcher<Form />- Error boundary structure
- Deferred data
- Real-world patterns
If you want a complete mental model of modern routing + data fetching in React, don’t miss the next post.
Top comments (0)