DEV Community

Cover image for Sync React State with URL Search Parameters
Harpreet Kaur
Harpreet Kaur

Posted on • Updated on

Sync React State with URL Search Parameters

Effortlessly synchronizing a React component's state with URL search parameters can be a common requirement when working with React applications that utilize React Router. In such scenarios, the useQueryParamsState hook provides an elegant solution, streamlining the management of URL query parameters.

Installation

To get started, ensure you have React and React Router installed in your project:

npm install react react-router-dom
Enter fullscreen mode Exit fullscreen mode

'useQueryParamsState' hook

import { useState, useEffect, Dispatch, SetStateAction } from "react";
import { useLocation } from "react-router-dom";

type UseQueryParamsStateReturnType<T> = [T, Dispatch<SetStateAction<T>>];

export const useQueryParamsState = <T>(
  param: string,
  initialState: T
): UseQueryParamsStateReturnType<T> => {
  const location = useLocation();

  // State for managing the value derived from the query parameter
  const [value, setValue] = useState<T>(() => {
    if (typeof window === "undefined") return initialState;

    // Parse query parameter value from the URL
    const { search } = window.location;
    const searchParams = new URLSearchParams(search);
    const paramValue = searchParams.get(param);

    return paramValue !== null ? JSON.parse(paramValue) as T : initialState;
  });

  useEffect(() => {
    const currentSearchParams = new URLSearchParams(window.location.search);

    // Update the query parameter with the current state value
    if (value !== null && value !== "") {
      currentSearchParams.set(param, JSON.stringify(value));
    } else {
      // Remove the query parameter if the value is null or empty
      currentSearchParams.delete(param);
    }

    // Update the URL with the modified search parameters
    const newUrl = [window.location.pathname, currentSearchParams.toString()]
      .filter(Boolean)
      .join("?");

    // Update the browser's history without triggering a page reload
    window.history.replaceState(window.history.state, "", newUrl);
  }, [param, value, location.pathname]);

  return [value, setValue];
};
Enter fullscreen mode Exit fullscreen mode

Usage

  1. Import the useQueryParamsState hook into your component:
import { useQueryParamsState } from './path-to/useQueryParamsState';
Enter fullscreen mode Exit fullscreen mode
  1. Use the hook within your component:
const MyComponent: React.FC = () => {
  const [paramValue, setParamValue] = useQueryParamsState<string>('myQueryParam', 'default');

  // Use paramValue and setParamValue as needed in your component
  return (
       // Your component JSX
  );
Enter fullscreen mode Exit fullscreen mode

Parameters

  • param (string): The name of the query parameter you want to sync with the component state.
  • initialState (T): The initial state for the component. This will be used when the query parameter is not present in the URL.

Return Value

The hook returns a tuple containing the current value of the query parameter and a function to update that value.

type UseQueryParamsStateReturnType<T> = [T, Dispatch<SetStateAction<T>>];
Enter fullscreen mode Exit fullscreen mode

Example

Consider a component that manages a search term based on a query parameter:

import { useQueryParamsState } from './path-to/useQueryParamsState';

const SearchComponent: React.FC = () => {
  const [searchTerm, setSearchTerm] = useQueryParamsState<string>('search', '');

  return (
    <div>
      <label>Search Term:</label>
      <input
        type="text"
        value={searchTerm}
        onChange={(e) => setSearchTerm(e.target.value)}
      />
      <p>Search Term: {searchTerm}</p>
    </div>
  );
};

Enter fullscreen mode Exit fullscreen mode

In this example, the SearchComponent automatically syncs its state with the 'search' query parameter in the URL, allowing users to bookmark or share specific search states.

Demo

Explore the interactive demo on CodeSandbox to see the useQueryParamsState hook in action:

Open in CodeSandbox

Explanation

The useQueryParamsState hook leverages React's state and effect hooks along with React Router's useLocation to manage the state of a specific query parameter. It handles parsing and updating the URL, providing a clean and reusable solution for components that need to interact with query parameters in a React Router environment. Developers can use this hook to create components that maintain their state based on URL query parameters without manually handling the complexities of URL manipulation.

Thanks For Reading 😉

Top comments (0)