npm.io
1.2.3 • Published 6 years ago

url-state-hook

Licence
MIT
Version
1.2.3
Deps
2
Size
620 kB
Vulns
0
Weekly
0
DeprecatedThis package is deprecated

url-state-hook

This is a React hook that is very similar to the built-in React.useState(), except that it mirrors the current state in the url as a query parameter. When a component that is using this hook mounts, if the url already contains a query-parameter value for the hook, it will use that as the initial state.

This allows page state to be maintained over various sessions, page refreshes, or back button navigation.

By default this hook it set up to use the default React Router from react-router-dom, but it can be configured to use other routers as well.

This is not a global state management hook

Install

NPM
npm install --save url-state-hook
Yarn
yarn add url-state-hook

Live Demo

https://williammetcalf.github.io/url-state-hook/

Basic Usage

import useUrlState from "url-state-hook";

const Example = () => {
  const [value, setValue] = useUrlState("s", "default value");

  return (
    <div>
      <input value={value} onChange={e => setValue(e.target.value)} />
    </div>
  );
};

Basic Array Usage

This package also exports a useUrlArrayState to handle array states. This is really just a wrapper around the default useUrlState with a customized decode option to handle deserializing the array.

import { useUrlArrayState } from "./use-state-hook";

const Example = () => {
  const [arrayState, setArrayState] = useUrlArrayState("arr", []);

  return (
    <div>
      <ul>
        {arrayState.map((val, idx) => (
          <li key={idx}>
            {val}
            <button
              onClick={() => {
                const newState = [...arrayState];
                newState.splice(idx, 1);
                setArrayState(newState);
              }}
            >
              x
            </button>
          </li>
        ))}
      </ul>
      <input
        onKeyPress={e => {
          if (e.key === "Enter") {
            const newState = [...arrayState];
            newState.push(e.target.value);
            e.target.value = "";
            setArrayState(newState);
          }
        }}
      />
    </div>
  );
};

Nextjs Example

By default useUrlState uses the built in React Router, but by configuring the options parameter other routers can be used instead. To do this, you must set the options.useCurrentUrlHook and options.updateUrlFn values. For example, here is a wrapper that can be used to make useUrlState work with Nextjs.

use-next-js-url-state.ts

import Router, { useRouter } from "next/router";
import useUrlState, { Options } from "url-state-hook";

function useNextjsUrlState<T>(
  key: string,
  defaultValue: T,
  options?: Omit<Options<T>, "useCurrentUrlHook" | "updateUrlFn">
) {
  const { route, pathname } = useRouter();
  const opts: Options<T> = {
    ...options,
    useCurrentUrlHook: () => {
      const { asPath } = useRouter();
      return asPath;
    },
    updateUrlFn: (searchString: string) => {
      typeof window === "undefined"
        ? () => {}
        : Router.replace(route, `${pathname}${searchString}`, {
            shallow: true
          });
    }
  };

  return useUrlState(key, defaultValue, opts);
}

export default useNextjsUrlState;

example.tsx

import React from "react";
import useNextjsUrlState from "./use-next-js-url-state";

const Example: FC = () => {
  const [value, setValue] = useNextjsUrlState("s", "default value");

  return (
    <div>
      <input value={value} onChange={e => setValue(e.target.value)} />
    </div>
  );
};

Api

Hook Parameters
param description required?
key url query-param name used when storing the state in the url yes
defaultValue default state value used when a initial value cannot be taken from the current url yes
options Options object no
Options
key description default value
decode function that deserializes the value stored in the url. Out of the box this hook will work with strings and numbers, but if a object or array is used as the state value, you need to supply a function to deserialize a string into the expected type
useCurrentUrlHook a function or React hook that returns the current url ReactRouterDom.useLocation()
updateUrlFn a function that can be used to update the current url ReactRouterDom.useHistory().replace
urlUpdateDebouce a time in MS to debounce the updating of the url, this is necessary to prevent race conditions where multiple useUrlState() hooks update their state at the same time 500

License

MIT williammetcalf


This hook is created using create-react-hook.