use-query-params icon indicating copy to clipboard operation
use-query-params copied to clipboard

Can't clear ArrayParam state when default value is not empty

Open oleksiy-letushev-axon opened this issue 3 years ago • 2 comments

When I have an ArrayParam state with a non-empty default array, I can't make it empty

const Arr = withDefault(ArrayParam, ["bar"]);

const Demo = () => {
  const [state, setState] = useQueryParam("foo", Arr);

  return (
    <div>
      <p>State: {JSON.stringify(state)}</p>
      <button
        onClick={() => {
          setState([]); // doesn't work
        }}
      >
        Clear state
      </button>
    </div>
  );
};

https://codesandbox.io/s/gallant-shockley-w2yojs?file=/src/App.js

oleksiy-letushev-axon avatar Nov 01 '22 17:11 oleksiy-letushev-axon

Empty arrays are tricky since there isn't really any invertible options from URLSearchParams or even query-string. How would you encode them in the array and get them decoded? Consider this code

      <p>URLSearchParams encode foo []: {JSON.stringify(new URLSearchParams({ foo: []}).toString())}</p>
      <p>URLSearchParams decode foo=: {JSON.stringify(new URLSearchParams("?foo=").get('foo'))}</p>
      <p>URLSearchParams decode foo=: {JSON.stringify(new URLSearchParams("?foo=").getAll('foo'))}</p>
      <p>query-string stringify encode foo []: {JSON.stringify(stringify({ foo: [] }))}</p>
      <p>query-string stringify decode "": {JSON.stringify(parse("")).foo}</p>

Screenshot 2022-11-01 at 11 30 54

I'm not really sure there's anything obvious we can do in the library to circumvent this. That being said, if you setState(['']) it will be decoded as [] in your sandbox and encoded in the URL as ?foo=

pbeshai avatar Nov 01 '22 18:11 pbeshai

Looks tricky but it works at least. Many thanks 🙏

oleksiy-letushev-axon avatar Nov 01 '22 19:11 oleksiy-letushev-axon