useHash
Hook to read and write the hash of the current url. It also updates the hash when the url changes.
Example
import useHash from "@/hooks/useHash";
export default function UseHashExample() {
const [hash, setHash] = useHash();
return (
<div className="flex flex-col items-center justify-center gap-4 p-4 text-ctp-text">
<p>Sets the hash of the url and updates the hash when the url changes.</p>
<p>The hash is {hash || "empty"}.</p>
<div className="flex flex-row items-center justify-center gap-4 p-4">
<button
className="rounded bg-ctp-green px-4 py-2 text-ctp-base"
onClick={() => setHash("hello")}
>
Set Hash to hello
</button>
<button
className="rounded bg-ctp-red px-4 py-2 text-ctp-base"
onClick={() => setHash("")}
>
Clear Hash
</button>
</div>
</div>
);
}
Code
import { useCallback, useEffect, useLayoutEffect, useState } from "react";
type UseHashReturn = [string, (newHash: string) => void];
const useIsomorphicLayoutEffect =
typeof window !== "undefined" ? useLayoutEffect : useEffect;
/**
* Hook to read and write the hash of the current url. It also updates the hash when the url changes.
* @returns {UseHashReturn} An array of two elements:
* 1. The current hash of the url.
* 2. A function to set the hash of the url.
*/
export default function useHash(): UseHashReturn {
const [hash, setHash] = useState(() => window.location.hash);
const onHashChange = useCallback(() => {
setHash(window.location.hash);
}, []);
useIsomorphicLayoutEffect(() => {
window.addEventListener("hashchange", onHashChange);
return () => {
window.removeEventListener("hashchange", onHashChange);
};
}, []);
const _setHash = useCallback(
(newHash: string) => {
if (newHash !== hash) {
window.location.hash = newHash;
}
},
[hash],
);
return [hash, _setHash] as const;
}