React Hooks

useQueryParamsState

Syncing React state with URL search parameters

September 06, 2021

Loading views
useQueryParamsState.js
import { useEffect, useState } from 'react';

export const useQueryParamsState = (param) => {
  const [value, setValue] = useState(() => {
    if (typeof window === 'undefined') return '';
    const { search } = window.location;
    const searchParams = new URLSearchParams(search);
    return searchParams.has(param) ? searchParams.get(param) : '';
  });

  useEffect(() => {
    const newUrl = new URL(window.location);
    if (value) {
      newUrl.searchParams.set(param, value);
    } else {
      newUrl.searchParams.delete(param);
    }
    window.history.replaceState(window.history.state, '', newUrl);
  }, [param, value]);

  return [value, setValue];
};

Context

It's a common practice to append search params to a URL so that the website could use that information to perform actions like searching, filtering and sorting.

This is a hook for text value searching by syncing your input state from React.useState with the URL search params. You can type in the input field or edit the search params in the URL. Then you can use the state to perform whatever side effects you want.

Usage

const FRUITS = ['apple', 'orange', 'watermelon'];

const App = () => {
  const [value, setValue] = useQueryParamsState('search');

  return (
    <>
      <input
        type="search"
        value={value}
        onChange={(e) => setValue(e.target.value)}
      />
      <ul>
        {FRUITS.filter((f) => f.startsWith(value)).map((f) => (
          <li key={f}>{f}</li>
        ))}
      </ul>
    </>
  );
};

Explanation

The hook takes an argument which the key you wish to refer to in the URL search params. For example, if you would like to search using ?q=someValue, then just call useQueryParamsState('q').

We are lazy initializing the value state by passing a function to useState. Kent C. Dodds wrote an article about this practice. The function grabs and initializes the state with any search params in the URL. This way we can dynamically route and search without relying on an input field.

The useEffect helps us to update the URL without refreshing by using history.replaceState.

Thanks For Reading 😉

If you would like to show your further support:

Buy Me a Book