| import { type ReadonlyURLSearchParams, usePathname, useRouter, useSearchParams } from 'next/navigation' |
| import { useCallback, useEffect, useMemo, useState } from 'react' |
|
|
| type AppsQuery = { |
| tagIDs?: string[] |
| keywords?: string |
| } |
|
|
| |
| function parseParams(params: ReadonlyURLSearchParams): AppsQuery { |
| const tagIDs = params.get('tagIDs')?.split(';') |
| const keywords = params.get('keywords') || undefined |
| return { tagIDs, keywords } |
| } |
|
|
| |
| function updateSearchParams(query: AppsQuery, current: URLSearchParams) { |
| const { tagIDs, keywords } = 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') |
| } |
|
|
| 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}`) |
| }, [router, pathname]) |
|
|
| |
| useEffect(() => { |
| const params = new URLSearchParams(searchParams) |
| updateSearchParams(query, params) |
| syncSearchParams(params) |
| }, [query, searchParams, syncSearchParams]) |
|
|
| return useMemo(() => ({ query, setQuery }), [query]) |
| } |
|
|
| export default useAppsQueryState |
|
|