2021-09-30
React Custom hook - useQueryString
markdown
Custom hook for simple get and set QueryString
[demo](tps://codesandbox.io/s/react-custom-hooks-usequerystring-vmc2g)
install package `react-router-dom`
```js
// 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(
    
+      
         
     ,
    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
* [QueryString - Wikipedia](https://en.wikipedia.org/wiki/Query_string)
* [React 中優雅使用網址參數 Query String - Jul 7, 2020 · Ryan Hsu](https://medium.com/itsoktomakemistakes/react-%E4%B8%AD%E5%84%AA%E9%9B%85%E4%BD%BF%E7%94%A8%E7%B6%B2%E5%9D%80%E5%8F%83%E6%95%B8-query-string-540bacd08486)
* [React Router, why useLocation and useHistory might return undefined](https://flaviocopes.com/react-router-uselocation-usehistory-undefined/)
* [React Router](https://reactrouter.com/web/guides/quick-start)
* [React Redux](https://react-redux.js.org/)
訂閱:
意見 (Atom)
 
