pbeshai / use-query-params

React Hook for managing state in URL query parameters with easy serialization.

Home Page:https://pbeshai.github.io/use-query-params

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Calling setQuery changes references to query params which are either objects or arrays

RomanTokar opened this issue · comments

Actual behavior

import { useEffect } from "react";
import { useQueryParams, withDefault, JsonParam } from "use-query-params";

export default function App() {
  const [query, setQuery] = useQueryParams({
    json: withDefault(JsonParam, {})
  });
  console.log(JSON.stringify(query));

  useEffect(() => {
    setQuery((prev) => ({ ...prev}));
  }, []);

  useEffect(() => {
    console.log("here");
  }, [query.json]);

  return null;
}

Console

image

https://codesandbox.io/s/use-query-params-jsonparam-issue-737tn4?file=/src/App.js

As you can see, whenever we call setQuery and change our params, a reference to query.json is changed and the second useEffect is called.

Expected behavior

I assume that it should work the same as behavior of the useState hook

import { useEffect, useState } from "react";

export default function App() {
  const [query, setQuery] = useState({
    json: {}
  });
  console.log(JSON.stringify(query));

  useEffect(() => {
    setQuery((prev) => ({ ...prev}));
  }, []);

  useEffect(() => {
    console.log("here");
  }, [query.json]);

  return null;
}

Console

image

And I would like to add that every render a reference to query object is being changed as well.

The issue is you're creating a new param each render by calling withDefault so useQueryParams doesn't know it can keep the old value. If you define your parameter type once, it will work as expected:

const MyParam = withDefault(JsonParam, {})
export default function App() {
  const [query, setQuery] = useQueryParams({
    json: MyParam
  });
  ...
}
``

@pbeshai Thanks for help and thanks for having such a great package.
I guess it would be great if that would be described in the documentation.