12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 |
- import { type ReadonlyURLSearchParams, usePathname, useRouter, useSearchParams } from 'next/navigation'
- import { useCallback, useEffect, useMemo, useState } from 'react'
- type AppsQuery = {
- tagIDs?: string[]
- keywords?: string
- isCreatedByMe?: boolean
- }
- function parseParams(params: ReadonlyURLSearchParams): AppsQuery {
- const tagIDs = params.get('tagIDs')?.split(';')
- const keywords = params.get('keywords') || undefined
- const isCreatedByMe = params.get('isCreatedByMe') === 'true'
- return { tagIDs, keywords, isCreatedByMe }
- }
- function updateSearchParams(query: AppsQuery, current: URLSearchParams) {
- const { tagIDs, keywords, isCreatedByMe } = query || {}
- if (tagIDs && tagIDs.length > 0)
- current.set('tagIDs', tagIDs.join(';'))
- else
- current.delete('tagIDs')
- if (keywords)
- current.set('keywords', keywords)
- else
- current.delete('keywords')
- if (isCreatedByMe)
- current.set('isCreatedByMe', 'true')
- else
- current.delete('isCreatedByMe')
- }
- function useAppsQueryState() {
- const searchParams = useSearchParams()
- const [query, setQuery] = useState<AppsQuery>(() => parseParams(searchParams))
- const router = useRouter()
- const pathname = usePathname()
- const syncSearchParams = useCallback((params: URLSearchParams) => {
- const search = params.toString()
- const query = search ? `?${search}` : ''
- router.push(`${pathname}${query}`, { scroll: false })
- }, [router, pathname])
-
- useEffect(() => {
- const params = new URLSearchParams(searchParams)
- updateSearchParams(query, params)
- syncSearchParams(params)
- }, [query, searchParams, syncSearchParams])
- return useMemo(() => ({ query, setQuery }), [query])
- }
- export default useAppsQueryState
|