Skip to content

Commit

Permalink
style: Use useSyncExternalStore in the React adapter
Browse files Browse the repository at this point in the history
  • Loading branch information
bartlangelaan committed Oct 30, 2024
1 parent 89f2b02 commit 6b2e0a2
Showing 1 changed file with 26 additions and 22 deletions.
48 changes: 26 additions & 22 deletions packages/nuqs/src/adapters/react.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,44 @@
import mitt from 'mitt'
import { useEffect, useState } from 'react'
import { useSyncExternalStore } from 'react'
import { renderQueryString } from '../url-encoding'
import type { AdapterOptions } from './defs'
import { createAdapterProvider } from './internal.context'

const emitter = mitt<{ update: URLSearchParams }>()
const emitter = mitt<{ update: void }>()

function subscribe(callback: () => void) {
emitter.on('update', callback)
window.addEventListener('popstate', callback)
return () => {
emitter.off('update', callback)
window.removeEventListener('popstate', callback)
}
}

function getSnapshot() {
return new URLSearchParams(location.search)
}

function getServerSnapshot() {
return new URLSearchParams()
}

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)
emitter.emit('update')
}

function useNuqsReactAdapter() {
const [searchParams, setSearchParams] = useState(() => {
if (typeof location === 'undefined') {
return new URLSearchParams()
}
return new URLSearchParams(location.search)
})
useEffect(() => {
// Popstate event is only fired when the user navigates
// via the browser's back/forward buttons.
const onPopState = () => {
setSearchParams(new URLSearchParams(location.search))
}
emitter.on('update', setSearchParams)
window.addEventListener('popstate', onPopState)
return () => {
emitter.off('update', setSearchParams)
window.removeEventListener('popstate', onPopState)
}
}, [])
const searchParams = useSyncExternalStore(
subscribe,
getSnapshot,
getServerSnapshot
)

return {
searchParams,
updateUrl
Expand Down

0 comments on commit 6b2e0a2

Please sign in to comment.