Capítulo 382 de 456
useParams (from next/navigation) reads a route's dynamic params from the current URL, and works identically in both Pages Router and App Router.
null during prerendering in the Pages Router (App Router never returns null).useParams() takes no arguments.router.isFallback-style caveat: for statically optimized Pages Router pages, returns null on first render until hydration completes.router.query: useParams returns only dynamic route segments; router.query (from useRouter) includes both dynamic segments and query string params.import { useParams } from 'next/navigation'
export default function ShopPage() {
const params = useParams<{ slug: string }>()
if (!params) {
return null // fallback UI while params not yet available
}
return <>Shop: {params.slug}</>
}
null prerendering state before showing the real param.import { useRouter } from 'next/router'
import { useParams } from 'next/navigation'
const router = useRouter()
const params = useParams()
// URL -> /shop/shoes?color=red
// router.query -> { slug: 'shoes', color: 'red' }
// params -> { slug: 'shoes' }
useParams and router.query.| Route | URL | useParams() |
|---|---|---|
pages/shop/page.js | /shop | {} |
pages/shop/[slug].js | /shop/1 | { slug: '1' } |
pages/shop/[tag]/[item].js | /shop/1/2 | { tag: '1', item: '2' } |
pages/shop/[...slug].js | /shop/1/2 | { slug: ['1', '2'] } |
null in Pages Router: causes hydration mismatches if you render param-dependent content before hydration completes.getServerSideProps, params are available immediately (no null state) since the page is always server-rendered.useParams is the cross-router-compatible way to build shared components between Pages Router and App Router.router.query, includes query string params too.null-on-prerender edge case.