-
-
Notifications
You must be signed in to change notification settings - Fork 254
Description
Bug Description
When using NuqsTestingAdapter in Storybook stories, queued URL updates set by one component are flushed (cleared) before React mounts sibling/child components that depend on the updated query parameter. This causes the dependent component to initialize with null instead of the queued value.
Reproduction
We have a Storybook story where a state machine transitions from a "triage drawer" to a "fix drawer":
- The triage drawer is opened via
NuqsTestingAdapter's initialsearchParams={{ 'triage-finding-id': 'finding-1' }} - During the triage flow, the state machine calls
setFindingFixFindingId('finding-1')viauseQueryState('fix-finding-id') - This queues a URL update for
fix-finding-id - On the next render,
NuqsTestingAdapterflushes the update queue (resets it), before the fix drawer component mounts - The fix drawer's
useQueryState('fix-finding-id')initializes withnullinstead of'finding-1'
Current Workaround
Setting resetUrlUpdateQueueOnMount={false} on NuqsTestingAdapter prevents the queue from being cleared, allowing the fix drawer to read the queued value:
<NuqsTestingAdapter
searchParams={{ 'triage-finding-id': FINDING_ID }}
resetUrlUpdateQueueOnMount={false}
>
<Story />
</NuqsTestingAdapter>However, this prop feels like a band-aid over a timing issue rather than a proper solution.
Better Alternative
We switched to using NuqsAdapter from nuqs/adapters/react-router/v7 (with storybook-addon-remix-react-router providing the React Router context) and setting initial search params via React Router's location.searchParams in the story parameters. This works correctly because nuqs reads/writes through React Router's state, which doesn't have the queue/flush timing issue.
// Decorator
<NuqsAdapter>
<Story />
</NuqsAdapter>
// Story parameters
parameters: {
reactRouter: {
location: {
searchParams: { 'triage-finding-id': FINDING_ID },
},
},
},Expected Behavior
NuqsTestingAdapter should not flush queued URL updates before all dependent components have had a chance to mount and read the queued values. The queue should be drained in a way that respects React's rendering lifecycle.
Environment
- nuqs: ^2.4.3
- React: 19.1.1
- Storybook: 8.x
- React Router: ^7.12.0