Skip to content

Commit afd34a5

Browse files
committed
ref: Pure internal state init function (#633)
- Follow the Rules of React to init the query ref once on mount - Remove access to the queued value, doesn't seem to change outcome of issue 359
1 parent e34684d commit afd34a5

File tree

4 files changed

+16
-22
lines changed

4 files changed

+16
-22
lines changed

packages/e2e/cypress/e2e/repro-359.cy.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ it('repro-359', () => {
1111
cy.get('#nuqss-component').should('have.text', '')
1212

1313
cy.contains('Component 1 (nuqs)').click()
14-
cy.wait(100)
14+
// cy.wait(100)
1515
cy.location('search').should('eq', '?param=comp1&component=comp1')
1616
cy.get('#comp1').should('have.text', 'comp1')
1717
cy.get('#comp2').should('not.exist')
@@ -21,7 +21,7 @@ it('repro-359', () => {
2121
cy.get('#nuqss-component').should('have.text', 'comp1')
2222

2323
cy.contains('Component 2 (nuqs)').click()
24-
cy.wait(100)
24+
// cy.wait(100)
2525
cy.location('search').should('eq', '?param=comp2&component=comp2')
2626
cy.get('#comp1').should('not.exist')
2727
cy.get('#comp2').should('have.text', 'comp2')
@@ -31,7 +31,7 @@ it('repro-359', () => {
3131
cy.get('#nuqss-component').should('have.text', 'comp2')
3232

3333
cy.contains('Component 1 (nuq+)').click()
34-
cy.wait(100)
34+
// cy.wait(100)
3535
cy.location('search').should('eq', '?param=comp1&component=comp1')
3636
cy.get('#comp1').should('have.text', 'comp1')
3737
cy.get('#comp2').should('not.exist')
@@ -41,7 +41,7 @@ it('repro-359', () => {
4141
cy.get('#nuqss-component').should('have.text', 'comp1')
4242

4343
cy.contains('Component 2 (nuq+)').click()
44-
cy.wait(100)
44+
// cy.wait(100)
4545
cy.location('search').should('eq', '?param=comp2&component=comp2')
4646
cy.get('#comp1').should('not.exist')
4747
cy.get('#comp2').should('have.text', 'comp2')

packages/nuqs/src/update-queue.ts

-4
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,6 @@ export function enqueueQueryStringUpdate<Value>(
5757
return serializedOrNull
5858
}
5959

60-
export function getQueuedValue(key: string) {
61-
return updateQueue.get(key) ?? null
62-
}
63-
6460
/**
6561
* Eventually flush the update queue to the URL query string.
6662
*

packages/nuqs/src/useQueryState.ts

+5-7
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import { emitter, type CrossHookSyncPayload } from './sync'
77
import {
88
FLUSH_RATE_LIMIT_MS,
99
enqueueQueryStringUpdate,
10-
getQueuedValue,
1110
scheduleFlushToURL
1211
} from './update-queue'
1312
import { safeParse } from './utils'
@@ -225,13 +224,12 @@ export function useQueryState<T = string>(
225224
const router = useRouter()
226225
// Not reactive, but available on the server and on page load
227226
const initialSearchParams = useSearchParams()
228-
const queryRef = React.useRef<string | null>(null)
227+
const queryRef = React.useRef<string | null>(
228+
initialSearchParams?.get(key) ?? null
229+
)
229230
const [internalState, setInternalState] = React.useState<T | null>(() => {
230-
const queueValue = getQueuedValue(key)
231-
const urlValue = initialSearchParams?.get(key) ?? null
232-
const value = queueValue ?? urlValue
233-
queryRef.current = value
234-
return value === null ? null : safeParse(parse, value, key)
231+
const query = initialSearchParams?.get(key) ?? null
232+
return query === null ? null : safeParse(parse, query, key)
235233
})
236234
const stateRef = React.useRef(internalState)
237235
debug(

packages/nuqs/src/useQueryStates.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import { emitter, type CrossHookSyncPayload } from './sync'
1111
import {
1212
FLUSH_RATE_LIMIT_MS,
1313
enqueueQueryStringUpdate,
14-
getQueuedValue,
1514
scheduleFlushToURL
1615
} from './update-queue'
1716
import { safeParse } from './utils'
@@ -74,9 +73,13 @@ export function useQueryStates<KeyMap extends UseQueryStatesKeysMap>(
7473
// Not reactive, but available on the server and on page load
7574
const initialSearchParams = useSearchParams()
7675
const queryRef = React.useRef<Record<string, string | null>>({})
76+
// Initialise the queryRef with the initial values
77+
if (Object.keys(queryRef.current).length !== Object.keys(keyMap).length) {
78+
queryRef.current = Object.fromEntries(initialSearchParams?.entries() ?? [])
79+
}
80+
7781
const [internalState, setInternalState] = React.useState<V>(() => {
7882
const source = initialSearchParams ?? new URLSearchParams()
79-
queryRef.current = Object.fromEntries(source.entries())
8083
return parseMap(keyMap, source)
8184
})
8285

@@ -99,8 +102,7 @@ export function useQueryStates<KeyMap extends UseQueryStatesKeysMap>(
99102
}, [
100103
Object.keys(keyMap)
101104
.map(key => initialSearchParams?.get(key))
102-
.join('&'),
103-
keys
105+
.join('&')
104106
])
105107

106108
// Sync all hooks together & with external URL changes
@@ -214,9 +216,7 @@ function parseMap<KeyMap extends UseQueryStatesKeysMap>(
214216
) {
215217
return Object.keys(keyMap).reduce((obj, key) => {
216218
const { defaultValue, parse } = keyMap[key]!
217-
const urlQuery = searchParams?.get(key) ?? null
218-
const queueQuery = getQueuedValue(key)
219-
const query = queueQuery ?? urlQuery
219+
const query = searchParams?.get(key) ?? null
220220
if (cachedQuery && cachedState && cachedQuery[key] === query) {
221221
obj[key as keyof KeyMap] = cachedState[key] ?? defaultValue ?? null
222222
return obj

0 commit comments

Comments
 (0)