mirror of
https://github.com/supabase/supabase.git
synced 2026-09-06 18:11:51 +08:00
## Problem Knip reports many duplicate exports (both named and default). Besides, we're moving away from default exports and even have an eslint rule to enforce it on new code. ## Solution - Cleanup those exports - Update imports when necessary No functional changes. If it builds, it's fine
66 lines
1.9 KiB
TypeScript
66 lines
1.9 KiB
TypeScript
import { useRouter } from 'next/router'
|
|
import { useCallback, useMemo, type Dispatch, type SetStateAction } from 'react'
|
|
|
|
import { useLatest } from '@/hooks/misc/useLatest'
|
|
|
|
export type UrlStateParams = {
|
|
[k: string]: string | string[] | undefined
|
|
}
|
|
|
|
/** @deprecated Use useQueryState from nuqs instead for URL state */
|
|
export function useUrlState<ValueParams extends UrlStateParams>({
|
|
replace = true,
|
|
arrayKeys = [],
|
|
}: {
|
|
/** Whether to use push state routing (working back button), or just replace the current URL
|
|
* @default true
|
|
*/
|
|
replace?: boolean
|
|
arrayKeys?: string[]
|
|
} = {}): [ValueParams, Dispatch<SetStateAction<ValueParams>>] {
|
|
const stringifiedArrayKeys = JSON.stringify(arrayKeys)
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
const arrayKeysSet = useMemo(() => new Set(arrayKeys), [stringifiedArrayKeys])
|
|
const router = useRouter()
|
|
|
|
const params: ValueParams = useMemo(() => {
|
|
return Object.fromEntries(
|
|
Object.entries(router.query).map(([key, value]) => {
|
|
if (arrayKeysSet.has(key)) {
|
|
return Array.isArray(value) ? [key, value] : [key, [value]]
|
|
}
|
|
|
|
return [key, value]
|
|
})
|
|
)
|
|
}, [arrayKeysSet, router.query])
|
|
|
|
const paramsRef = useLatest(params)
|
|
|
|
const setParams: Dispatch<SetStateAction<ValueParams>> = useCallback(
|
|
(newParams) => {
|
|
const params = paramsRef.current
|
|
|
|
const nextParams = typeof newParams === 'function' ? newParams(params) : newParams
|
|
let newQuery = Object.fromEntries(
|
|
Object.entries({ ...params, ...nextParams }).filter(([, value]) => Boolean(value))
|
|
)
|
|
|
|
const replaceOrPush = replace ? router.replace : router.push
|
|
|
|
replaceOrPush(
|
|
{
|
|
pathname: router.pathname,
|
|
query: newQuery,
|
|
},
|
|
undefined,
|
|
{ shallow: true, scroll: false }
|
|
)
|
|
},
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
[router, replace]
|
|
)
|
|
|
|
return [params, setParams] as const
|
|
}
|