Skip to content

React Tutorial Routing and Application Structure

Route Parameters and Query Strings in React Router

Lesson 107 of 156 2 min read By Deepak Paswan Updated Oct 10, 2026

Full-project lesson · needs Node.js, npm and real project files, so it does not run in the in-page playground.

Many pages show one item out of many: /products/42, /users/ada, /articles/my-post. You do not write a route for each product. You write one route with a dynamic segment and read the value from the URL.

Dynamic segments and useParams

A segment that starts with : is a placeholder. useParams() returns an object with the actual values:

src/App.jsx
JSX
import { Routes, Route, NavLink, Link, useParams, useSearchParams } from 'react-router'

const PRODUCTS = [
  { id: 1, name: 'Keyboard' },
  { id: 2, name: 'Mouse' },
  { id: 3, name: 'Monitor' },
]

function Home() {
  return <h1>Home page</h1>
}

function Products() {
  const [searchParams] = useSearchParams()
  const sort = searchParams.get('sort')
  const list = sort === 'name' ? [...PRODUCTS].sort((a, b) => a.name.localeCompare(b.name)) : PRODUCTS

  return (
    <div>
      <h1>Our products</h1>
      <p>{sort === 'name' ? 'Sorted by name' : 'Default order'}</p>
      <ul>
        {list.map((p) => (
          <li key={p.id}>
            <Link to={`/products/${p.id}`}>{p.name}</Link>
          </li>
        ))}
      </ul>
    </div>
  )
}

function ProductDetail() {
  const { id } = useParams() // always a string
  const product = PRODUCTS.find((p) => p.id === Number(id))

  if (!product) {
    return (
      <div>
        <h1>We could not find product {id}</h1>
        <Link to="/products">Back to the list</Link>
      </div>
    )
  }

  return (
    <div>
      <h1>Product {product.id}: {product.name}</h1>
      <Link to="/products">Back to the list</Link>
    </div>
  )
}

function App() {
  return (
    <div>
      <nav style={{ display: 'flex', gap: 16 }}>
        <NavLink to="/" end>Home</NavLink>
        <NavLink to="/products">Products</NavLink>
      </nav>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/products" element={<Products />} />
        <Route path="/products/:id" element={<ProductDetail />} />
      </Routes>
    </div>
  )
}

export default App

Tested in a browser: the list links go to detail pages, a direct visit to /products/3 works, an unknown id shows a friendly message, and ?sort=name changes the list.

Points to remember:

  • :id becomes params.id. Name segments for what they are: :productId, :slug, :username.
  • Values are always strings. useParams() gives "2", not 2. Convert with Number(id), and decide what to do if the result is NaN.
  • Parameters can be wrong. A user can type any URL. Always handle “no such item” (see Not Found Pages), and never trust a parameter for security decisions; the server must check access.
  • Several parameters work as expected: /users/:userId/posts/:postId gives { userId, postId }.

Query strings: useSearchParams

A query string (?sort=name&page=2) stores optional settings: filters, sort order, page number, search text. React Router wraps the browser’s URLSearchParams:

App.jsx
JSX
const [searchParams, setSearchParams] = useSearchParams()

const page = Number(searchParams.get('page') ?? 1)
const q = searchParams.get('q') ?? ''

setSearchParams({ q: 'router', page: '1' })          // /products?q=router&page=1
setSearchParams((prev) => {                          // keep the other params
  prev.set('page', String(page + 1))
  return prev
})

Why use the URL for filters and paging instead of state?

  • The user can refresh and keep the same view.
  • The view can be bookmarked or shared.
  • Back and Forward step through the changes.

Pair it with Search and Filtering and Pagination.

Path parameters or query parameters?

Use a path parameter forUse a query parameter for
Which resource: /products/42How to show it: ?sort=price&page=2
Required valuesOptional values
IdentityFilters, search, paging

Other helpful hooks

HookReturns
useLocation()The current location: pathname, search, hash, state
useMatch(pattern)Whether the URL matches a pattern, with params
useNavigate()A function to navigate from code

Key points

  • :name in the path and useParams() read dynamic segments; the values are strings.
  • Always handle missing or invalid parameters.
  • Keep filters, search and page numbers in the query string with useSearchParams.