Last active
January 14, 2023 00:37
-
-
Save intrnl/da3e3a07837cb2e93e52e62770a727d7 to your computer and use it in GitHub Desktop.
React hook for managing search params with serialization (using react-router v6 and serialize-query-params)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { type ReactNode } from 'react'; | |
import { useSearchParams } from 'react-router-dom'; | |
import { type QueryParamConfig } from 'serialize-query-params'; | |
export * from 'serialize-query-params'; | |
const SearchParamsContext = React.createContext<ReturnType<typeof useSearchParams> | null>(null); | |
interface SearchParamsProviderProps { | |
children?: ReactNode; | |
} | |
export const SearchParamsProvider = (props: SearchParamsProviderProps) => { | |
const tuple = useSearchParams(); | |
return ( | |
<SearchParamsContext.Provider value={tuple}> | |
{props.children} | |
</SearchParamsContext.Provider> | |
); | |
}; | |
export const useSearchParam = <D, E>(name: string, config: QueryParamConfig<E, D>) => { | |
const [searchParams, setSearchParams] = React.useContext(SearchParamsContext)!; | |
const values = searchParams.getAll(name); | |
const decoded = React.useMemo(() => { | |
return config.decode(values) ?? undefined; | |
}, [values.join('\0')]); | |
const update = React.useCallback((next: E, replace?: boolean) => { | |
const nextSearchParams = new URLSearchParams(searchParams); | |
const encoded = config.encode(next); | |
if (encoded == null) { | |
nextSearchParams.delete(name); | |
} else if (Array.isArray(encoded)) { | |
nextSearchParams.delete(name); | |
for (const v of encoded) { | |
if (v == null) { | |
continue; | |
} | |
nextSearchParams.append(name, v); | |
} | |
} else { | |
nextSearchParams.set(name, encoded); | |
} | |
setSearchParams(nextSearchParams, { replace }); | |
}, [searchParams]); | |
return [decoded, update] as const; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment