Capítulo 13 de 57

Chapter 13: Migrate from React Router

Core Idea

Migrating from React Router to TanStack Router is a checklist-driven process: install TanStack Router, optionally uninstall react-router-dom to surface TypeScript errors on every remaining import, rebuild routes/root route/router instance, swap Link/useNavigate/Outlet/useParams, and move useSearchParams state into validateSearch plus useSearch.

Key Concepts

  • Diagnostic technique: Uninstalling react-router-dom forces TypeScript compile errors at every leftover import, giving a reliable checklist of what still needs conversion (faster than grepping manually).
  • Blank UI symptom: An error like "cannot use useNavigate outside of context" in the console typically means a stray React Router API is still being called somewhere.
  • No confirmed gradual migration: The docs note it's unclear whether a gradual migration (running both routers simultaneously) is supported; having multiple router providers at once is undesirable.
  • Link differences: TanStack Router's Link requires a literal to path prop, plus a params prop for dynamic segments, e.g. params={{ orderId: order.id }}.
  • useNavigate differences: Same to/params pattern as Link is used with the @tanstack/react-router useNavigate hook.
  • Search params migration: React Router's useSearchParams hook is replaced by defining a validateSearch property on the route, then reading values with useSearch({ from: fullPath }) and updating them via Link's search prop.
  • useParams differences: Requires a from property naming the literal route path (e.g. useParams({ from: "/orders/$orderId" })), then accessing fields off the returned params object.

Code Examples

const { page } = useSearch({ from: productPage.fullPath })
  • What it demonstrates: Reading a search param value the TanStack Router way, replacing React Router's useSearchParams hook.
const params = useParams({ from: '/orders/$orderId' })
// params.orderId
  • What it demonstrates: Reading a dynamic path param with the required from property pointing at the literal route path.

Key Takeaways

  1. Uninstall react-router-dom early in the migration to let TypeScript surface every remaining call site needing conversion, this is faster and more reliable than manual searching.
  2. Systematically replace Link, useNavigate, Outlet, useParams, and useSearchParams one at a time; each has a direct but not identical TanStack Router equivalent requiring to/params/from wiring.
  3. Move any search-param defaults out of ad hoc useSearchParams logic and into a route's validateSearch, this is the biggest structural change, not just an API rename.

Connects To

  • Ch 4: Decisions on DX explains why TanStack Router's route/context model differs structurally from React Router's, informing why this isn't a pure find-and-replace migration.
  • Ch 5: Comparison shows the underlying feature gaps (typesafe search params, typesafe context) that motivate migrating in the first place.
  • Ch 14: Migrate from React Location covers the analogous migration for TanStack Router's spiritual predecessor.