Chalarangelo/30-seconds-of-code

View on GitHub
content/snippets/react/s/use-search-param.md

Summary

Maintainability
Test Coverage
---
title: React useSearchParam hook
type: snippet
language: react
tags: [hooks,state,effect]
cover: coffee-phone-tray-3
dateModified: 2021-10-13
---

Tracks the browser's location search param.

- Use the `useCallback()` hook to create a callback that uses the `URLSearchParams` constructor to get the current value of `param`.
- Use the `useState()` hook to create a state variable that holds the current value of the `param`.
- Use the `useEffect()` hook to set appropriate event listeners to update the state variable when mounting and clean them up when unmounting.

```jsx
const useSearchParam = param => {
  const getValue = React.useCallback(
    () => new URLSearchParams(window.location.search).get(param),
    [param]
  );

  const [value, setValue] = React.useState(getValue);

  React.useEffect(() => {
    const onChange = () => {
      setValue(getValue());
    };

    window.addEventListener('popstate', onChange);
    window.addEventListener('pushstate', onChange);
    window.addEventListener('replacestate', onChange);

    return () => {
      window.removeEventListener('popstate', onChange);
      window.removeEventListener('pushstate', onChange);
      window.removeEventListener('replacestate', onChange);
    };
  }, []);

  return value;
};

const MyApp = () => {
  const post = useSearchParam('post');

  return (
    <>
      <p>Post param value: {post || 'null'}</p>
      <button
        onClick={() =>
          history.pushState({}, '', location.pathname + '?post=42')
        }
      >
        View post 42
      </button>
      <button onClick={() => history.pushState({}, '', location.pathname)}>
        Exit
      </button>
    </>
  );
};

ReactDOM.createRoot(document.getElementById('root')).render(
  <MyApp />
);
```