Skip to content

Instantly share code, notes, and snippets.

@BollaBerg
Created March 18, 2024 09:13
Show Gist options
  • Save BollaBerg/de628e19448f24eedd9ee630c4b75a17 to your computer and use it in GitHub Desktop.
Save BollaBerg/de628e19448f24eedd9ee630c4b75a17 to your computer and use it in GitHub Desktop.
A React-hook for using search params, when not using React Router
import { useCallback, useEffect, useState } from 'react';
const SEARCH_PARAMS_EVENT_KEY = 'SEARCH-PARAMS-UPDATED';
interface UseSearchParams {
searchParams: URLSearchParams;
setSearchParam: (key: string, value: string) => void;
removeSearchParam: (key: string) => void;
}
function updateURL(searchParams: URLSearchParams) {
const baseURL = window.location.href.split(/[?#]/)[0];
const searchParamsPart = searchParams.size ? `?${searchParams}` : '';
history.replaceState(null, '', `${baseURL}${searchParamsPart}`);
}
function getSearchParams(): URLSearchParams {
if (typeof document === 'undefined') return new URLSearchParams();
return new URL(document.location.href).searchParams;
}
export default function useSearchParams(): UseSearchParams {
const [searchParams, setLocalSearchParams] = useState<URLSearchParams>(getSearchParams());
const setSearchParam = useCallback(
(key: string, value: string) => {
setLocalSearchParams(prev => {
const copy = new URLSearchParams(prev);
copy.set(key, value);
updateURL(copy);
return copy;
});
if (typeof window !== 'undefined') window.dispatchEvent(new Event(SEARCH_PARAMS_EVENT_KEY));
},
[setLocalSearchParams],
);
const removeSearchParam = useCallback(
(key: string) => {
setLocalSearchParams(prev => {
const copy = new URLSearchParams(prev);
copy.delete(key);
updateURL(copy);
return copy;
});
if (typeof window !== 'undefined') window.dispatchEvent(new Event(SEARCH_PARAMS_EVENT_KEY));
},
[setLocalSearchParams],
);
const handleSearchParamsUpdate = useCallback(() => {
setLocalSearchParams(getSearchParams());
}, [setLocalSearchParams]);
useEffect(() => {
if (typeof window === 'undefined') return;
window.addEventListener(SEARCH_PARAMS_EVENT_KEY, handleSearchParamsUpdate);
return () => window.removeEventListener(SEARCH_PARAMS_EVENT_KEY, handleSearchParamsUpdate);
}, [handleSearchParamsUpdate]);
return { searchParams, setSearchParam, removeSearchParam };
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment