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
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
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.