How to Use Query Parameters in React Router DOM

When building a modern React application, it’s common to pass data through the URL—especially for filtering, searching, sorting, or pagination. Instead of creating new routes for every variation, you can use query parameters, which provide a powerful way to pass optional data through the URL.

In react-router-dom, query parameters are not handled in the same way as path parameters, but with a bit of setup using the useSearchParams hook (introduced in React Router v6), managing query strings becomes clean and straightforward.

In this blog, we’ll dive deep into how to use query parameters in react-router-dom, with clear examples and real-world use cases.


What Are Query Parameters?

Query parameters are the key-value pairs added to the end of a URL after a question mark (?). For example:

/products?category=electronics&page=2

Here:

  • category is a query parameter with the value electronics
  • page is another parameter with the value 2

They’re used to provide optional, non-hierarchical information that doesn’t change the main route but influences what is shown on the page.


Why Use Query Parameters in React?

Query parameters are useful for:

  • Filtering results (e.g., ?category=shoes)
  • Searching (e.g., ?query=react)
  • Sorting (e.g., ?sort=price-asc)
  • Pagination (e.g., ?page=3)
  • Retaining state after refresh or navigation

Unlike state variables, query parameters persist in the URL and can be bookmarked or shared with others.


Getting Started with useSearchParams

To use query parameters in a React Router v6+ app, you’ll need the useSearchParams hook.

Here’s how to get started.

Installation (if not already installed)

npm install react-router-dom

Accessing Query Parameters

Let’s say you have a route like this:

/products?category=laptop&page=2

And your component is:

import { useSearchParams } from "react-router-dom"

export default function ProductsPage() {
  const [searchParams] = useSearchParams()
  const category = searchParams.get("category")
  const page = searchParams.get("page")

  return (
    <div>
      <h1>Products</h1>
      <p>Category: {category}</p>
      <p>Page: {page}</p>
    </div>
  )
}

With searchParams.get("key"), you can extract any parameter from the query string.


Setting Query Parameters

To update or set query parameters, use the second value returned by useSearchParams.

const [searchParams, setSearchParams] = useSearchParams()

const handleFilterChange = (newCategory) => {
  setSearchParams({ category: newCategory, page: 1 })
}

This will update the URL to something like:

/products?category=shoes&page=1

setSearchParams() automatically updates the URL and re-renders the component with the new values.


Keeping Existing Parameters

If you want to change just one parameter while preserving the others:

const [searchParams, setSearchParams] = useSearchParams()

const handleSortChange = (sortValue) => {
  searchParams.set("sort", sortValue)
  setSearchParams(searchParams)
}

This approach ensures the rest of the parameters stay intact.


Full Example: Product List with Filtering and Pagination

import { useSearchParams } from "react-router-dom"

function ProductList() {
  const [searchParams, setSearchParams] = useSearchParams()

  const category = searchParams.get("category") || "all"
  const page = parseInt(searchParams.get("page")) || 1

  const handleCategoryChange = (e) => {
    searchParams.set("category", e.target.value)
    searchParams.set("page", 1) // reset page when category changes
    setSearchParams(searchParams)
  }

  const goToPage = (newPage) => {
    searchParams.set("page", newPage)
    setSearchParams(searchParams)
  }

  return (
    <div>
      <h2>Product List</h2>

      <label>Category:</label>
      <select value={category} onChange={handleCategoryChange}>
        <option value="all">All</option>
        <option value="shoes">Shoes</option>
        <option value="electronics">Electronics</option>
      </select>

      <p>Current Page: {page}</p>
      <button onClick={() => goToPage(page - 1)} disabled={page === 1}>Previous</button>
      <button onClick={() => goToPage(page + 1)}>Next</button>
    </div>
  )
}

This example demonstrates a common use case for query parameters: combining filters and pagination while keeping the URL in sync.


Using URLSearchParams Directly

useSearchParams is a wrapper around the native URLSearchParams API. If you ever want to use it manually:

const params = new URLSearchParams(window.location.search)
const query = params.get("query")

This approach works but doesn’t re-render the component on change, which is why useSearchParams is preferred in React apps.


Syncing Query Params with State

Sometimes you want your query params and component state to stay in sync. You can do this by initializing state from query params:

const [searchParams, setSearchParams] = useSearchParams()
const [searchTerm, setSearchTerm] = useState(searchParams.get("query") || "")

And then updating both when the user types:

const handleSearch = () => {
  setSearchParams({ query: searchTerm })
}

This ensures the UI reflects the current URL state and vice versa.


Tips for Using Query Parameters Effectively

  • Always validate query param values (e.g., for page numbers or filters)
  • Use defaults when a parameter is missing
  • Avoid too many params in a single URL—it can get messy
  • Debounce search input when syncing to query strings
  • Keep param names consistent and meaningful

Conclusion

Query parameters are a powerful tool for building interactive, shareable, and dynamic experiences in React applications. Thanks to react-router-dom‘s useSearchParams hook, handling them is cleaner and easier than ever before.

With this approach, you can build robust features like filters, search pages, pagination systems, or user-specific views—all while maintaining a clean and accessible URL structure.

Mastering query parameters will make your React apps not only more functional but also more user-friendly and SEO-aware.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top