React: From Components to Production · Routing with React Router

Keeping State in the URL

Use search params for filters, pagination and shareable views.

Filters, sorting, tabs and pagination usually belong in the URL search params: they survive reloads, can be shared and bookmarked, and work with back/forward navigation. useSearchParams() reads and updates them. Parse and validate params with defaults, and use replace for frequent updates (like typing) to avoid flooding history.

import { useSearchParams } from "react-router";

export function ProductFilters() {
  const [params, setParams] = useSearchParams();
  const category = params.get("category") ?? "all";
  const page = Math.max(1, Number(params.get("page")) || 1);

  function update(key: string, value: string | null) {
    setParams((prev) => {
      const next = new URLSearchParams(prev);
      if (value) next.set(key, value); else next.delete(key);
      if (key !== "page") next.delete("page");      // reset pagination on filter change
      return next;
    }, { replace: key === "q" });
  }

  return (
    <>
      <select value={category} onChange={(e) => update("category", e.target.value === "all" ? null : e.target.value)}>
        <option value="all">All</option><option value="books">Books</option>
      </select>
      <Pagination page={page} onChange={(p) => update("page", String(p))} />
    </>
  );
}

Common pitfalls

  • Duplicating URL state in useState and letting them diverge.
  • Not validating params (users can type anything).
  • Pushing a history entry on every keystroke.

Key points

  • URL state is shareable and survives reloads
  • Validate and default params
  • Use replace for rapid updates

Further reading: React Router: useSearchParams

Practice questions

Which UI state should live in the URL?

Answer

State users expect to share, bookmark or restore with back/forward: filters, search queries, sort order, pagination and selected tabs.

Why reset the page parameter when a filter changes?

Answer

The current page number may not exist in the new filtered result set, leaving users on an empty page.

Open in the app to mark lessons complete, take notes and track your progress.