Created
March 18, 2024 09:13
-
-
Save BollaBerg/de628e19448f24eedd9ee630c4b75a17 to your computer and use it in GitHub Desktop.
A React-hook for using search params, when not using React Router
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 { 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