mirror of
https://github.com/CompassConnections/Compass.git
synced 2026-03-25 18:13:48 -04:00
53 lines
1.6 KiB
TypeScript
53 lines
1.6 KiB
TypeScript
import {debounce, pickBy} from 'lodash'
|
|
import {useRouter} from 'next/router'
|
|
import {useEffect, useState} from 'react'
|
|
|
|
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})]
|
|
}
|