07 — Routing in React — URLs as State, React Router and TanStack Router
"Just navigating between pages" was my routing model, and it made routers look like page-switching utilities. The framing that straightened it out: in a single-page application, the URL is just another piece of state, and a router is the library that maps URL state to which components render. [1] Once I saw the URL as state, the rest followed — links are state setters, the back button is an undo, and route params are state that flows into components.
Why a single-page app needs a router at all
A traditional multi-page site navigates by full document reloads — each link fetches a fresh HTML page from the server. A React SPA loads once and then rewrites parts of the page in place, so "navigation" can't rely on the browser's default reload behavior. A client-side router fills that gap by:
- intercepting link clicks and pushState calls so they update the URL without a full reload,
- reading the current URL and deciding which route component to mount,
- syncing with the browser's back/forward buttons so history still works.
The payoff is the SPA's signature: instant page transitions, no white flash, persistent UI state across "pages." The cost is that I now own the URL-to-component mapping, which is what a router library manages for me.
React Router: the default
React Router is the standard library for this [1][2]. It provides a declarative way to define routes — each route maps a URL pattern to a component — and handles the link interception, history, and nested routing. The core pieces:
- <BrowserRouter> wraps the app and enables client-side routing.
- <Routes> and <Route> declare the URL → component mapping, including dynamic segments like :id.
- <Link> renders an anchor that changes the URL without a reload.
- useParams reads dynamic segments; useNavigate pushes programmatically.
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/users/:id" element={<UserProfile />} />
<Route path="*" element={<NotFound />} />
</Routes>
</BrowserRouter>Routes nest, so a /dashboard/settings route can render <Dashboard> with an <Outlet> for its child routes. That nesting model is the part I underused at first — it's how shared layouts (a sidebar that stays put while the inner panel changes) are built.
TanStack Router: the type-safe challenger
TanStack Router is a newer, more ambitious router [3]. Its distinguishing trait is full type safety end to end — route params, search/query parameters, and links are all typed, so a typo in a path or a wrong param type is a compile error rather than a runtime 404. It also treats search params as first-class typed state, with built-in validation.
// a route definition infers its params and search schema
export const Route = createFileRoute('/users/$userId')({
validateSearch: (search) => ({ tab: search.tab ?? 'overview' }),
component: UserProfile,
});The tradeoff is a steeper setup — file-based routing convention, a build step, and a stricter way of thinking. The roadmap lists it alongside React Router [3], and the way I read it: TanStack Router is the choice when type safety around navigation and search params is worth the setup cost (large apps with complex query-param state), while React Router remains the sensible default for most projects.
How I use this
For most projects I default to React Router — it's battle-tested, the API is stable, and nested routes with <Outlet> cover the layout cases I hit. I treat the URL as state from day one: anything the user might want to share or bookmark (a filter, a selected tab, a detail view) goes into the URL as a path segment or search param, not just into local component state. That habit is what makes "deep links work" a side effect of how I build rather than a feature I bolt on. When a project's search-param state gets complex enough that I'm writing manual parsers and validators, that's the signal to evaluate TanStack Router — the type safety around params and search pays for itself at scale.
References
[1] LogRocket, "How to use routing in React JS: a comprehensive guide," blog.logrocket.com, 2023. [Online]. Available: https://blog.logrocket.com/react-router-v6-guide/
[2] React Router team, "React Router," 2024. [Online]. Available: https://reactrouter.com/
[3] TanStack, "TanStack Router documentation," 2024. [Online]. Available: https://tanstack.com/router/latest/docs/framework/react/overview
[4] pedrotech, "React Router v7: a crash course," dev.to, 2024. [Online]. Available: https://dev.to/pedrotech/react-router-v7-a-crash-course-2m86
Knowledge check · Question 1 of 5
In a React SPA, what is the URL?
Comments
Leave a Comment
You must be signed in to comment
0 Comments
No comments yet. Be the first to comment!