Programmatically Updating Query Parameters in React Router

2024-07-27

Query parameters, also known as URL search parameters, are key-value pairs appended to a URL after a question mark (?). They are used to pass additional information to a web page without affecting the path itself. For instance, in the URL https://www.example.com/products?category=electronics&sort=price, the query parameters are category=electronics and sort=price.

Updating Query Parameters Programmatically

React Router provides a convenient hook called useNavigate (or useHistory in older versions) to manipulate the URL, including updating query parameters. Here's a step-by-step breakdown:

  1. Import useNavigate:

    import { useNavigate } from 'react-router-dom';
    
  2. Access Navigation Function:

    Inside your React component, call the useNavigate hook to get a function that allows you to programmatically change the URL.

    const navigate = useNavigate();
    
  3. Construct the New Query String:

    • Use the URLSearchParams object (available in modern browsers) to create or modify the query string portion of the URL.
    • Set or modify key-value pairs as needed:
    const newSearchParams = new URLSearchParams(window.location.search);
    newSearchParams.set('filter', 'active'); // Add a new parameter
    newSearchParams.delete('sort'); // Remove an existing parameter
    // ... modify other parameters
    
  4. Update the URL:

    • Call the navigate function, passing an object with the updated search string:
    navigate({ search: newSearchParams.toString() });
    

Complete Example:

import React, { useState } from 'react';
import { useNavigate } from 'react-router-dom';

function ProductList() {
  const [filter, setFilter] = useState('');
  const navigate = useNavigate();

  const handleFilterChange = (event) => {
    setFilter(event.target.value);
  };

  const handleFilterSubmit = () => {
    const newSearchParams = new URLSearchParams(window.location.search);
    newSearchParams.set('filter', filter);
    navigate({ search: newSearchParams.toString() });
  };

  return (
    <div>
      <select value={filter} onChange={handleFilterChange}>
        <option value="">All Products</option>
        <option value="active">Active Products</option>
        {/* ... other options */}
      </select>
      <button onClick={handleFilterSubmit}>Filter</button>
    </div>
  );
}

export default ProductList;

In this example, selecting a filter option from the dropdown updates the filter state variable. Clicking the "Filter" button triggers the handleFilterSubmit function, which constructs the new query string with the selected filter and updates the URL using navigate.

Additional Considerations:

  • Remember that updating the URL triggers a re-render of the component at the new route, so handle state management accordingly.



import React, { useState } from 'react';
import { useNavigate } from 'react-router-dom';

function ProductList() {
  const [filter, setFilter] = useState('');
  const navigate = useNavigate();

  const handleFilterChange = (event) => {
    setFilter(event.target.value);
  };

  const handleFilterSubmit = () => {
    const newSearchParams = new URLSearchParams(window.location.search);
    newSearchParams.set('filter', filter); // Add or update the 'filter' parameter
    navigate({ search: newSearchParams.toString() }); // Update URL with new search string
  };

  return (
    <div>
      <select value={filter} onChange={handleFilterChange}>
        <option value="">All Products</option>
        <option value="active">Active Products</option>
        {/* ... other options */}
      </select>
      <button onClick={handleFilterSubmit}>Filter</button>
    </div>
  );
}

export default ProductList;

Explanation:

  • Imports useState and useNavigate from react-router-dom.
  • Uses state (filter) to store the selected filter value.
  • handleFilterChange updates the state based on the dropdown selection.
  • handleFilterSubmit constructs the new query string using URLSearchParams.
    • Sets or updates the filter parameter based on the selected value.
    • Calls navigate to update the URL with the new search string.

Example 2: Adding or Removing Query Parameters on Button Click

import React, { useState } from 'react';
import { useNavigate } from 'react-router-dom';

function MyComponent() {
  const [showDetails, setShowDetails] = useState(false);
  const navigate = useNavigate();

  const handleToggleDetails = () => {
    const newSearchParams = new URLSearchParams(window.location.search);
    if (showDetails) {
      newSearchParams.delete('details'); // Remove 'details' parameter if present
    } else {
      newSearchParams.set('details', 'true'); // Add 'details' parameter
    }
    navigate({ search: newSearchParams.toString() });
    setShowDetails(!showDetails); // Update state to reflect change
  };

  return (
    <div>
      <button onClick={handleToggleDetails}>
        {showDetails ? 'Hide Details' : 'Show Details'}
      </button>
    </div>
  );
}

export default MyComponent;
  • Manages the showDetails state to track whether details are visible.
  • handleToggleDetails handles button clicks:
    • Creates a URLSearchParams object.
    • If showDetails is true, removes the details parameter (hiding details).
    • If showDetails is false, adds the details parameter with a value (showing details).
    • Updates the URL using navigate.
    • Toggles the showDetails state to reflect the change in button text.

Key Points:

  • Use URLSearchParams for efficient query string manipulation.
  • Consider using libraries like query-string for advanced scenarios.
  • Update component state for UI changes based on query parameter updates.



  • This hook provides a more concise way to interact with query parameters within your component.
  • It returns an array containing two elements:
    • The current URLSearchParams object representing the query string.
    • A setter function to update the search params.
import { useSearchParams } from 'react-router-dom';

function MyComponent() {
  const [searchParams, setSearchParams] = useSearchParams();
  const filter = searchParams.get('filter'); // Access existing parameter

  const handleFilterChange = (newFilter) => {
    setSearchParams({ filter: newFilter }); // Update single parameter
  };

  // ... other logic
}

history.push with Search String (Older React Router Versions)

  • If you're using an older version of React Router (before v6), you can use history.push along with a constructed search string to update the URL.
import { useHistory } from 'react-router-dom';

function MyComponent() {
  const history = useHistory();

  const handleFilterChange = (newFilter) => {
    const newSearchParams = new URLSearchParams(window.location.search);
    newSearchParams.set('filter', newFilter);
    history.push({ search: newSearchParams.toString() });
  };

  // ... other logic
}

Custom Hook (For Reusability)

  • Create a reusable custom hook that encapsulates the logic for updating query params.
import { useNavigate } from 'react-router-dom';

function useUpdateQueryParams() {
  const navigate = useNavigate();

  const updateParams = (newParams) => {
    const searchParams = new URLSearchParams(window.location.search);
    Object.entries(newParams).forEach(([key, value]) => searchParams.set(key, value));
    navigate({ search: searchParams.toString() });
  };

  return updateParams;
}
  • Use this hook in your components for cleaner code:
import { useUpdateQueryParams } from './useUpdateQueryParams';

function MyComponent() {
  const updateParams = useUpdateQueryParams();

  const handleFilterChange = (newFilter) => {
    updateParams({ filter: newFilter });
  };

  // ... other logic
}

Choosing the Right Method:

  • If you're using React Router v6.4 or above, useSearchParams is the recommended approach for its simplicity.
  • For older versions or complex scenarios involving multiple parameter updates, consider a custom hook.
  • Use history.push sparingly as useNavigate provides a more general way to handle navigation.

reactjs react-router



Understanding React JSX: Selecting "selected" on a Selected <select> Option

Understanding the <select> Element:The <select> element in HTML represents a dropdown list.It contains one or more <option> elements...


Understanding Virtual DOM: The Secret Behind React's Performance

Imagine the Virtual DOM (VDOM) as a lightweight, in-memory copy of your React application's actual DOM (Document Object Model). It's a tree-like structure that mirrors the elements on your web page...


Keeping Your React Components Clean: Conditional Rendering and DRY Principles

ReactJS provides several ways to conditionally render elements based on certain conditions. Here are the common approaches:...


Understanding Parent-Child Communication in React: The Power of Props

Here's a breakdown of the process:Parent Component:Define the data you want to pass as props within the parent component...


React: Why You Can't Use 'for' Attribute Directly on Label Elements

In JavaScript, for is a reserved keyword used for loop constructs.When you directly use for as an attribute in JSX (React's syntax for creating HTML-like elements), it conflicts with this keyword's meaning...



reactjs react router

Understanding the Code for Rerendering React Views on Resize

Concept:In React, components are typically rendered once when they're first mounted to the DOM.However, in certain scenarios


Accessing Custom Attributes from Event Handlers in React

React allows you to define custom attributes on HTML elements using the data-* prefix. These attributes are not part of the standard HTML specification and are used to store application-specific data


Unveiling the Secrets of React's Performance: How Virtual DOM Beats Dirty Checking

Directly updating the DOM (Document Object Model) in JavaScript can be slow. The DOM represents the structure of your web page


Communicating Between React Components: Essential Techniques

React applications are built from independent, reusable components. To create a cohesive user experience, these components often need to exchange data or trigger actions in each other


Unlocking Dynamic Content in React: Including Props Within JSX Quotes

In React, components can receive data from parent components through properties called props.These props allow you to customize the behavior and appearance of child components