React Custom hook - useQueryString

Custom hook for simple get and set QueryString

install package react-router-dom

// src/index.js
  import { StrictMode } from "react";
  import ReactDOM from "react-dom";
+ import { BrowserRouter as Router } from "react-router-dom";

  import App from "./App";

  const rootElement = document.getElementById("root");
  ReactDOM.render(
    <StrictMode>
+      <Router>
        <App />
+      </Router>
    </StrictMode>,
    rootElement
  );

Add useQueryString.js

// src/hooks/useQueryString.js
import React from "react";
import { useLocation, useHistory } from "react-router-dom";
import { shallowEqual } from "react-redux";

const useQueryString = () => {
  const location = useLocation();
  const history = useHistory();
  const { search } = location;
  const [value, setValue] = React.useState({});

  React.useEffect(() => {
    let qs = Object.fromEntries(new URLSearchParams(search));
    if (!shallowEqual(qs, value)) {
      setValue(qs);
    }
  }, [search]); // eslint-disable-line react-hooks/exhaustive-deps

  return {
    value,
    set: (params) =>
      history.push({
        pathname: location.pathname,
        search: new URLSearchParams({ ...value, ...params }).toString()
      })
  };
};

export default useQueryString;

I use shallowEqual function check queryString is changed.

// shallowEqual.js in react-redux
function is(x, y) {
  if (x === y) {
    return x !== 0 || y !== 0 || 1 / x === 1 / y;
  } else {
    return x !== x && y !== y;
  }
}

export default function shallowEqual(objA, objB) {
  if (is(objA, objB)) return true;

  if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
    return false;
  }

  var keysA = Object.keys(objA);
  var keysB = Object.keys(objB);
  if (keysA.length !== keysB.length) return false;

  for (var i = 0; i < keysA.length; i++) {
    if (!Object.prototype.hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
      return false;
    }
  }

  return true;
}

How to use useQueryString()

const qs = useQueryString();

set value to url

qs.set({"name": "value"});
qs.set({"age": "19"});

get value

console.log(qs.value.name);
console.log(qs.value.age);

References