Skip to content

Instantly share code, notes, and snippets.

@albingroen
Last active August 16, 2022 18:55
Show Gist options
  • Save albingroen/416535e0f6ac82045c2ab3c71b74f214 to your computer and use it in GitHub Desktop.
Save albingroen/416535e0f6ac82045c2ab3c71b74f214 to your computer and use it in GitHub Desktop.
useQueryParam
export default function useQueryParam<T>(
key: string,
push: (path: string) => void,
defaultValue?: T,
): [T, (value: T) => void] {
const { pathname, search } = location
const query = new URLSearchParams(search)
const rawValue = query.get(key)
// Here we determine whether or not the default value, (and prob. the value)
// is an array or not, to know whether to parse the url param or not later.
const isDefaultValueArray = Array.isArray(defaultValue)
// Here we also try ot determine whether or not the actual value from the
// array is an array or not (but a bit hackier since its a string).
const isRawValueArray = rawValue?.startsWith('[') && rawValue?.endsWith(']')
// This would preferably be a function to increase readability, but since the
// var should be instantly accessible we need to use a inline ternary here.
const value = (
rawValue
? isDefaultValueArray
? isRawValueArray
? (JSON.parse(rawValue) as T)
: [rawValue]
: rawValue
: defaultValue
) as T
const setValue = (newValue: T) => {
// If the default value is an array, we stringify the new value
if (isDefaultValueArray) {
query.set(key, JSON.stringify(newValue))
} else {
// Otherwise we simply make sure it's a string
query.set(key, String(newValue))
}
// Lastly, we go ahead and push the new path
push(pathname + `?${query.toString()}`)
}
return [value, setValue]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment