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);