From ee38db351e22fe1e9b89c572062d0592f06b2fdd Mon Sep 17 00:00:00 2001 From: Francois Best Date: Tue, 19 Nov 2024 11:05:11 +0100 Subject: [PATCH 1/3] test: Add failing test for issue 774 --- packages/e2e/next/cypress/e2e/repro-774.cy.js | 17 ++++++++ .../e2e/next/src/app/app/repro-774/page.tsx | 41 +++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 packages/e2e/next/cypress/e2e/repro-774.cy.js create mode 100644 packages/e2e/next/src/app/app/repro-774/page.tsx diff --git a/packages/e2e/next/cypress/e2e/repro-774.cy.js b/packages/e2e/next/cypress/e2e/repro-774.cy.js new file mode 100644 index 000000000..bde2d78d6 --- /dev/null +++ b/packages/e2e/next/cypress/e2e/repro-774.cy.js @@ -0,0 +1,17 @@ +/// + +describe('repro-774', () => { + it('updates internal state on navigation', () => { + cy.visit('/app/repro-774') + cy.contains('#hydration-marker', 'hydrated').should('be.hidden') + cy.get('#trigger-a').click() + cy.get('#value-a').should('have.text', 'a') + cy.get('#value-b').should('be.empty') + cy.get('#link').click() + cy.get('#value-a').should('be.empty') + cy.get('#value-b').should('be.empty') + cy.get('#trigger-b').click() + cy.get('#value-a').should('be.empty') + cy.get('#value-b').should('have.text', 'b') + }) +}) diff --git a/packages/e2e/next/src/app/app/repro-774/page.tsx b/packages/e2e/next/src/app/app/repro-774/page.tsx new file mode 100644 index 000000000..ed90cdf39 --- /dev/null +++ b/packages/e2e/next/src/app/app/repro-774/page.tsx @@ -0,0 +1,41 @@ +'use client' + +import Link from 'next/link' +import { parseAsString, useQueryStates } from 'nuqs' +import { Suspense } from 'react' + +export default function Home() { + return ( + <> + + + + + + ) +} + +const searchParams = { + a: parseAsString.withDefault(''), + b: parseAsString.withDefault('') +} + +function Client() { + const [{ a, b }, setSearchParams] = useQueryStates(searchParams) + return ( + <> + + + {a} + {b} + + ) +} From dcaa285395afdee4db37f23daa6f404bc306e860 Mon Sep 17 00:00:00 2001 From: Francois Best Date: Tue, 19 Nov 2024 11:23:25 +0100 Subject: [PATCH 2/3] fix: Update state cache when syncing from useSearchParams --- packages/nuqs/src/useQueryStates.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/nuqs/src/useQueryStates.ts b/packages/nuqs/src/useQueryStates.ts index 6ece5c74f..58f6be6d0 100644 --- a/packages/nuqs/src/useQueryStates.ts +++ b/packages/nuqs/src/useQueryStates.ts @@ -133,6 +133,7 @@ export function useQueryStates( queryRef.current, stateRef.current ) + stateRef.current = state setInternalState(state) }, [ Object.values(resolvedUrlKeys) From 6249b6c36b739fe7b41be555c03821a57fb605e3 Mon Sep 17 00:00:00 2001 From: Francois Best Date: Tue, 19 Nov 2024 11:23:41 +0100 Subject: [PATCH 3/3] ref: Rename output object --- packages/nuqs/src/useQueryStates.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/nuqs/src/useQueryStates.ts b/packages/nuqs/src/useQueryStates.ts index 58f6be6d0..849e7315a 100644 --- a/packages/nuqs/src/useQueryStates.ts +++ b/packages/nuqs/src/useQueryStates.ts @@ -275,7 +275,7 @@ function parseMap( cachedQuery?: Record, cachedState?: NullableValues ): NullableValues { - return Object.keys(keyMap).reduce((obj, stateKey) => { + return Object.keys(keyMap).reduce((out, stateKey) => { const urlKey = urlKeys?.[stateKey] ?? stateKey const { parse } = keyMap[stateKey]! const queuedQuery = getQueuedValue(urlKey) @@ -284,15 +284,15 @@ function parseMap( ? (searchParams?.get(urlKey) ?? null) : queuedQuery if (cachedQuery && cachedState && cachedQuery[urlKey] === query) { - obj[stateKey as keyof KeyMap] = cachedState[stateKey] ?? null - return obj + out[stateKey as keyof KeyMap] = cachedState[stateKey] ?? null + return out } const value = query === null ? null : safeParse(parse, query, stateKey) - obj[stateKey as keyof KeyMap] = value ?? null + out[stateKey as keyof KeyMap] = value ?? null if (cachedQuery) { cachedQuery[urlKey] = query } - return obj + return out }, {} as NullableValues) }