Closed bartlangelaan closed 2 weeks ago
Thanks for the great report, much appreciated!
Looks like we could apply the same trick as in #718, I'll give it a try and report back.
Looking at your example, the SlowComponent blocks the main thread, something which is not recommended by the React team.
If this is a way to mock actual slow render performance in your application, I'd suggest looking into startTransition and useDeferredValue, which can help deferring state updates with large impacts to when React is not busy processing user inputs.
As for nuqs, this isn't something that was introduced in v2, as I can reproduce it in your sandbox with nuqs@1.20.0. Another tip to improve performance is to lower the useQueryState(s) hooks as much as possible in your React tree. They are all synced together so you may even duplicate/separate calls to the same query key in different parts of your app. No need to lift the state up: it's already lifted as high as possible (the URL) for you.
Another thing you can try if you can't avoid slow renders, is to use uncontrolled inputs: this lets the browser deal with internal updates of the input state, and only gives you the onChange event handler, that you can pass feed to a startTransition
to lower the rendering priority to yield to more important user events:
https://codesandbox.io/p/devbox/nuqs-forked-77szd3
<input
defaultValue={value}
onChange={(e) =>
startTransition(() => {
setValue(e.target.value);
})
}
/>
One caveat of uncontrolled inputs is that they won't be reactive to live changes of the URL from another source (<Link>
, router calls, or another useQueryState(s)
update elsewhere in the same page). But if they don't have to be (you're just interested in initialising it to the URL value on mount), they can be a great source of optimisation.
Context
What's your version of
nuqs
?What framework are you using?
Which version of your framework are you using?
Description
When using
useQueryState
in the pages router, and calling the updater frequently, sometimes the state gets set to an intermediate value. It looks like theuseSearchParams
has a small delay, and overrides the state from nuqs.Take this component as example:
When typing 'test', it sometimes ends up with 'tet'.
Debug log:
Reproduction
https://codesandbox.io/p/devbox/vpnm88
Type in the field to see the bug in action.