Skip to content

Instantly share code, notes, and snippets.

@TorvaldsDB
Created May 12, 2022 13:34
Show Gist options
  • Save TorvaldsDB/1f43bb380f6c4feb7fd2b3ea903974b9 to your computer and use it in GitHub Desktop.
Save TorvaldsDB/1f43bb380f6c4feb7fd2b3ea903974b9 to your computer and use it in GitHub Desktop.
/*
This hook allows reading and setting url query params.
Usage example:
const [query, setQuery] = useQueryParam({
name: 'q',
});
*/
import { useState, useEffect, useCallback } from 'react';
import { useHistory, useLocation } from 'react-router-dom';
interface Props {
name: string;
initialValue?: string;
}
type Result<T = string> = [T, React.Dispatch<React.SetStateAction<T>>];
const useQueryParam = <T extends string = string>(
{
name,
initialValue,
}: Props,
): Result<T> => {
const history = useHistory();
const location = useLocation();
const getParams = useCallback(
() => new URLSearchParams(location.search),
[location.search],
);
const defaultValue = (initialValue || '') as T;
const [value, setValue] = useState(getParams().get(name) as T || defaultValue);
useEffect(
() => {
const params = getParams();
const paramValue = params.get(name);
// Updates page url only when values are not equal
if (value !== paramValue && !(value === defaultValue && paramValue === null)) {
if (value === defaultValue) {
params.delete(name);
} else {
params.set(name, value);
params.sort();
}
history.push({
pathname: location.pathname,
search: params.toString(),
hash: location.hash,
});
}
},
[defaultValue, getParams, history, location, name, value],
);
return [value, setValue];
};
export default useQueryParam;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment