Skip to content

Instantly share code, notes, and snippets.

@kokotom
Created December 24, 2022 15:12
Show Gist options
  • Save kokotom/8aa1d611a459f55ea776ffb57147c94d to your computer and use it in GitHub Desktop.
Save kokotom/8aa1d611a459f55ea776ffb57147c94d to your computer and use it in GitHub Desktop.
A hook for remix to read and update search params without causing navigation.
import {useCallback, useState} from 'react'
import {createSearchParams} from 'react-router-dom'
import {useLocation} from '@remix-run/react'
export type ParamKeyValuePair = [string, string]
type URLSearchParamsInit =
| string
| ParamKeyValuePair[]
| Record<string, string | string[]>
| URLSearchParams
type SetURLSearchParams = (
nextInit?:
| URLSearchParamsInit
| ((prev: URLSearchParams) => URLSearchParamsInit),
) => void
export function useStateOnlySearchParams() {
let {search} = useLocation()
let [state, setState] = useState<URLSearchParams>(
new URLSearchParams(createSearchParams(search)),
)
let setSearchParams = useCallback<SetURLSearchParams>(
nextInit => {
const newSearchParams = createSearchParams(
typeof nextInit === 'function' ? nextInit(state) : nextInit,
)
setState(newSearchParams)
window.history.replaceState(
{},
'',
hasAnySearchParams(newSearchParams)
? `?${newSearchParams.toString()}`
: '',
)
},
[state],
)
return [state, setSearchParams] as const
}
function hasAnySearchParams(searchParams: URLSearchParams) {
return searchParams.toString().length > 0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment