Last active
December 11, 2024 15:59
-
-
Save dclstn/45d0421ad72dc21667d2a15c9cbb3743 to your computer and use it in GitHub Desktop.
A useful hook for managing query state
This file contains hidden or 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 from 'react'; | |
| interface useQueryStateConfig<T> { | |
| parse?: (value: string) => T; | |
| serialize?: (value: T) => string; | |
| defaultValue: T; | |
| } | |
| export default function useQueryState<T>( | |
| key: string, | |
| config: useQueryStateConfig<T> | |
| ): readonly [T, (value: T | null) => void] { | |
| const [value, setValue] = React.useState<T>(() => { | |
| const query = new URLSearchParams(window.location.search).get(key); | |
| if (query == null) { | |
| return config.defaultValue; | |
| } | |
| if (config.parse == null) { | |
| return query as T; | |
| } | |
| return config.parse(query); | |
| }); | |
| const setQuery = React.useCallback( | |
| (value: T | null): void => { | |
| setValue(value as T); | |
| const newParams = new URLSearchParams(window.location.search); | |
| if (value != null && config.serialize != null) { | |
| value = config.serialize(value) as T; | |
| } | |
| if (value === config.defaultValue) { | |
| newParams.delete(key); | |
| } else { | |
| newParams.set(key, value as unknown as string); | |
| } | |
| if (newParams.toString().length === 0) { | |
| window.history.replaceState(null, '', window.location.pathname); | |
| return; | |
| } | |
| window.history.replaceState(null, '', `${window.location.pathname}?${newParams}`); | |
| }, | |
| // eslint-disable-next-line react-hooks/exhaustive-deps | |
| [key, config.serialize, config.defaultValue] | |
| ); | |
| return [value, setQuery] as const; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment