Skip to content

Commit 9421c80

Browse files
committed
feat: Allow shallow: false updates to reload the page in React SPA
1 parent 803d3e0 commit 9421c80

File tree

1 file changed

+50
-9
lines changed

1 file changed

+50
-9
lines changed

packages/nuqs/src/adapters/react.ts

+50-9
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,45 @@
11
import mitt from 'mitt'
2-
import { useEffect, useState } from 'react'
2+
import {
3+
createContext,
4+
createElement,
5+
useContext,
6+
useEffect,
7+
useMemo,
8+
useState,
9+
type ReactNode
10+
} from 'react'
311
import { renderQueryString } from '../url-encoding'
412
import { createAdapterProvider } from './lib/context'
513
import type { AdapterOptions } from './lib/defs'
614
import { patchHistory, type SearchParamsSyncEmitter } from './lib/patch-history'
715

816
const emitter: SearchParamsSyncEmitter = mitt()
917

10-
function updateUrl(search: URLSearchParams, options: AdapterOptions) {
11-
const url = new URL(location.href)
12-
url.search = renderQueryString(search)
13-
const method =
14-
options.history === 'push' ? history.pushState : history.replaceState
15-
method.call(history, history.state, '', url)
16-
emitter.emit('update', search)
18+
function generateUpdateUrlFn(reloadPageOnShallowFalseUpdates: boolean) {
19+
return function updateUrl(search: URLSearchParams, options: AdapterOptions) {
20+
const url = new URL(location.href)
21+
url.search = renderQueryString(search)
22+
if (reloadPageOnShallowFalseUpdates && options.shallow === false) {
23+
const method =
24+
options.history === 'push' ? location.assign : location.replace
25+
method.call(location, url)
26+
} else {
27+
const method =
28+
options.history === 'push' ? history.pushState : history.replaceState
29+
method.call(history, history.state, '', url)
30+
}
31+
emitter.emit('update', search)
32+
}
1733
}
1834

35+
const NuqsReactAdapterContext = createContext({
36+
reloadPageOnShallowFalseUpdates: false
37+
})
38+
1939
function useNuqsReactAdapter() {
40+
const { reloadPageOnShallowFalseUpdates } = useContext(
41+
NuqsReactAdapterContext
42+
)
2043
const [searchParams, setSearchParams] = useState(() => {
2144
if (typeof location === 'undefined') {
2245
return new URLSearchParams()
@@ -36,13 +59,31 @@ function useNuqsReactAdapter() {
3659
window.removeEventListener('popstate', onPopState)
3760
}
3861
}, [])
62+
const updateUrl = useMemo(
63+
() => generateUpdateUrlFn(reloadPageOnShallowFalseUpdates),
64+
[reloadPageOnShallowFalseUpdates]
65+
)
3966
return {
4067
searchParams,
4168
updateUrl
4269
}
4370
}
4471

45-
export const NuqsAdapter = createAdapterProvider(useNuqsReactAdapter)
72+
const NuqsReactAdapter = createAdapterProvider(useNuqsReactAdapter)
73+
74+
export function NuqsAdapter({
75+
children,
76+
reloadPageOnShallowFalseUpdates = false
77+
}: {
78+
children: ReactNode
79+
reloadPageOnShallowFalseUpdates?: boolean
80+
}) {
81+
return createElement(
82+
NuqsReactAdapterContext.Provider,
83+
{ value: { reloadPageOnShallowFalseUpdates } },
84+
createElement(NuqsReactAdapter, null, children)
85+
)
86+
}
4687

4788
/**
4889
* Opt-in to syncing shallow updates of the URL with the useOptimisticSearchParams hook.

0 commit comments

Comments
 (0)