47ng / nuqs

Type-safe search params state manager for React frameworks - Like useState, but stored in the URL query string.
https://nuqs.47ng.com
MIT License
4.73k stars 103 forks source link

fix: Ensure referential stability for values #617

Closed franky47 closed 2 months ago

franky47 commented 2 months ago

Before this PR, any update of a search param (via nuqs or otherwise) would trigger all the parsers to run, causing unstable references for non-primitive states (objects, arrays, maybe even Dates?).

This caused effects to re-run needlessly, and it is wasteful: we already have the values, and other search params which haven't changed don't need to be parsed again.

This PR implements a cache of the serialized query string value along with the cache of the internal state (using React refs), and checks for a change before calling the parsers if needed.

Related tweet: https://x.com/fortysevenfx/status/1828786748354408489

Caveats

This is an edge case, but having two different parsers on the same key (eg: parseAsInteger and parseAsFloat) will result in the latest updated value being propagated to all the hooks registered on the same key.

Example: if setting foo to 1.234 via parseAsFloat, a hook listening to foo with parseAsInteger will have a state of 1.234, not 1. Before this PR, the state would flash first with 1.234, then the parser would run and correct it to 1.

Anyway, this is not a recommended use of the library (one key, one parser, then derive state if needed).

vercel[bot] commented 2 months ago

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
nuqs ✅ Ready (Inspect) Visit Preview 💬 Add feedback Sep 2, 2024 6:29pm
pkg-pr-new[bot] commented 2 months ago

Open in Stackblitz

pnpm add https://pkg.pr.new/nuqs@617

commit: 88d2c5e

github-actions[bot] commented 2 months ago

:tada: This PR is included in version 1.19.0-beta.1 :tada:

The release is available on:

Your semantic-release bot :package::rocket:

github-actions[bot] commented 2 months ago

:tada: This PR is included in version 1.19.0 :tada:

The release is available on:

Your semantic-release bot :package::rocket: