Skip to content

Commit

Permalink
feat: Allow shallow: false updates to reload the page in React SPA
Browse files Browse the repository at this point in the history
  • Loading branch information
franky47 committed Feb 7, 2025
1 parent 803d3e0 commit 9421c80
Showing 1 changed file with 50 additions and 9 deletions.
59 changes: 50 additions & 9 deletions packages/nuqs/src/adapters/react.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,45 @@
import mitt from 'mitt'
import { useEffect, useState } from 'react'
import {
createContext,
createElement,
useContext,
useEffect,
useMemo,
useState,
type ReactNode
} from 'react'
import { renderQueryString } from '../url-encoding'
import { createAdapterProvider } from './lib/context'
import type { AdapterOptions } from './lib/defs'
import { patchHistory, type SearchParamsSyncEmitter } from './lib/patch-history'

const emitter: SearchParamsSyncEmitter = mitt()

function updateUrl(search: URLSearchParams, options: AdapterOptions) {
const url = new URL(location.href)
url.search = renderQueryString(search)
const method =
options.history === 'push' ? history.pushState : history.replaceState
method.call(history, history.state, '', url)
emitter.emit('update', search)
function generateUpdateUrlFn(reloadPageOnShallowFalseUpdates: boolean) {
return function updateUrl(search: URLSearchParams, options: AdapterOptions) {
const url = new URL(location.href)
url.search = renderQueryString(search)
if (reloadPageOnShallowFalseUpdates && options.shallow === false) {
const method =
options.history === 'push' ? location.assign : location.replace
method.call(location, url)
} else {
const method =
options.history === 'push' ? history.pushState : history.replaceState
method.call(history, history.state, '', url)
}
emitter.emit('update', search)
}
}

const NuqsReactAdapterContext = createContext({
reloadPageOnShallowFalseUpdates: false
})

function useNuqsReactAdapter() {
const { reloadPageOnShallowFalseUpdates } = useContext(
NuqsReactAdapterContext
)
const [searchParams, setSearchParams] = useState(() => {
if (typeof location === 'undefined') {
return new URLSearchParams()
Expand All @@ -36,13 +59,31 @@ function useNuqsReactAdapter() {
window.removeEventListener('popstate', onPopState)
}
}, [])
const updateUrl = useMemo(
() => generateUpdateUrlFn(reloadPageOnShallowFalseUpdates),
[reloadPageOnShallowFalseUpdates]
)
return {
searchParams,
updateUrl
}
}

export const NuqsAdapter = createAdapterProvider(useNuqsReactAdapter)
const NuqsReactAdapter = createAdapterProvider(useNuqsReactAdapter)

export function NuqsAdapter({
children,
reloadPageOnShallowFalseUpdates = false
}: {
children: ReactNode
reloadPageOnShallowFalseUpdates?: boolean
}) {
return createElement(
NuqsReactAdapterContext.Provider,
{ value: { reloadPageOnShallowFalseUpdates } },
createElement(NuqsReactAdapter, null, children)
)
}

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

0 comments on commit 9421c80

Please sign in to comment.