State is not resetting on page change
zbeyens opened this issue ยท 6 comments
Context
What's your version of nuqs
?
"nuqs": "^1.17.1",
Next.js information (obtained by running next info
):
Operating System:
Platform: darwin
Arch: arm64
Version: Darwin Kernel Version 23.4.0: Fri Mar 15 00:12:49 PDT 2024; root:xnu-10063.101.17~1/RELEASE_ARM64_T6020
Binaries:
Node: 20.12.1
npm: 10.5.0
Yarn: 1.22.19
pnpm: 8.15.6
Relevant Packages:
next: 14.1.4
eslint-config-next: 14.1.4
react: 18.2.0
react-dom: 18.2.0
typescript: 5.4.5
Next.js Config:
output: N/A
Are you using:
- โ The app router
Description
On page change to a route without search params, useQueryStates
value is not resetting but useSearchParams
is correctly doing so.
Here is my workaround:
const searchParams = useSearchParams();
const queryState = Object.fromEntries(searchParams.entries());
queryState.pageIndex = queryState.pageIndex ?? 0;
queryState.pageSize = queryState.pageSize ?? defaultPageSize;
queryState.sort = queryState.sort ?? defaultSort;
const [, setQueryState] = useQueryStates(
{
pageIndex: parseAsInteger.withDefault(0),
pageSize: parseAsInteger.withDefault(defaultPageSize),
sort: parseAsString.withDefault(defaultSort),
}
);
Is there a way to get the same value than useSearchParams
?
Do you have a reproductible example?
Here it is https://github.com/zbeyens/shadcn-table/tree/nuqs
You can click on "Variant" in the header to switch page to /variant
, where I would expect sort=title.asc
to be set as search param, which is the case on page refresh.
2024-04-18.at.15.40.48.mp4
From what I can see in your example:
- The /variant page uses the same
useQueryStates
hook, but with a different default value for thesort
key (createdAt.desc
on /,title.asc
on /variant). - When navigating to the /variant page, there is a series of effects that adds the search params back to the URL.
There is a weird behaviour to understand about Next.js client side navigation between pages: it will render the destination page in the background before updating the URL and swapping the component trees. When that background rendering is done, it is done with the current URL (the one that you were on before clicking the <Link>
). There have been issues reported with this in #524 (comment).
Now what happens in this case is the following:
- You click the link to navigate to
/variant
- The destination page component renders, but with the populated URL query string
sort=createdAt.desc
- The useQueryStates hook in
useDataTable
is initialised with this value - Next.js changes the URL to
/variant
and starts running effects - Those effects now ignore the new default value, as there is already a state in place, so it syncs that state back into the URL.
Note: commenting out the useEffect that reads the sorting
object and updates the search params solves the issue, at the expense of not having the sort option explicitly reflected in the URL. This might help you figure out another way to sync that particular piece of state.
Now I do agree that this all feels like a bug, unfortunately nuqs
doesn't have a way to know the destination URL when a page transition occurs, since the rendering of the destination page is done ahead of time by Next.js. I'll create a simpler reproduction case for this behaviour and will report it to the Next.js team.
Thanks for detailed answer. That makes sense. If I understand correctly, nuqs
can't reset the state on page transition since the destination URL (and its search params) are unknown. Perhaps having an option to reset the query state on page transition would be nice so it can pick the new defaults on the next page mount.
Actually there was a bug in the hook initialisation code, which used the URL location.search
(which is not yet updated when mounting the destination page) rather than useSearchParams
, which contains the correct destination search params.
I was afraid a fix would break compatibility with older versions of Next.js, but it looks like CI is all green (see #544).
Could you try 1.17.2-beta.1
and see if it fixes the issue on your end please? I tried it on a clone of your reproduction repo and it correctly switches to sort=title.asc
when navigating to /variant
.
๐ This issue has been resolved in version 1.17.2 ๐
The release is available on:
Your semantic-release bot ๐ฆ๐