mirror of
https://github.com/CompassConnections/Compass.git
synced 2025-12-23 22:18:43 -05:00
56 lines
1.6 KiB
TypeScript
56 lines
1.6 KiB
TypeScript
import { useRouter } from 'next/router'
|
|
import { useEffect, useState } from 'react'
|
|
import { pickBy, debounce } from 'lodash'
|
|
|
|
type UrlParams = Record<string, string | undefined>
|
|
|
|
// for updating multiple query params
|
|
export const usePersistentQueriesState = <T extends UrlParams>(
|
|
defaultValue: T
|
|
): [T, (newState: Partial<T>) => void, boolean] => {
|
|
const [state, setState] = useState(defaultValue)
|
|
|
|
const router = useRouter()
|
|
const [ready, setReady] = useState(false)
|
|
|
|
// On page load, initialize the state to the current query params once.
|
|
useEffect(() => {
|
|
if (router.isReady) {
|
|
setState({ ...defaultValue, ...router.query })
|
|
setReady(true)
|
|
}
|
|
}, [router.isReady])
|
|
|
|
const setRouteQuery = debounce((newQuery: string) => {
|
|
const { pathname } = router
|
|
const q = newQuery ? '?' + encodeURI(newQuery) : ''
|
|
router.replace(pathname + q)
|
|
}, 200)
|
|
|
|
const updateState = (update: Partial<T>) => {
|
|
// Include current query because it might have been updated by another component.
|
|
const newState = { ...state, ...router.query, ...update } as T
|
|
setState(newState)
|
|
const query = pickBy(newState, (v) => v)
|
|
const newQuery = Object.keys(query)
|
|
.map((key) => `${key}=${query[key]}`)
|
|
.join('&')
|
|
setRouteQuery(newQuery)
|
|
}
|
|
|
|
return [state, updateState, ready]
|
|
}
|
|
|
|
export const usePersistentQueryState = <K extends string>(
|
|
key: K,
|
|
defaultValue: string
|
|
): [string | undefined, (newState: string) => void] => {
|
|
const [state, updateState] = usePersistentQueriesState({
|
|
[key]: defaultValue,
|
|
})
|
|
return [
|
|
state ? state[key] : undefined,
|
|
(newState: string) => updateState({ [key]: newState }),
|
|
]
|
|
}
|