Custom Hook in React (TypeScript)
It contains muliple custom hooks that I made in the journey.
Table of Contents
useScrollPercentage()
hooks/useScrollPercentage.ts
import { useEffect, useState, useCallback } from "react";
export default function useScrollPercentage() {
// fifteen
const [scrollPercentage, setScrollPercentage] = useState(0);
function getScrollPercent(): number {
var h = document.documentElement;
var b = document.body;
return (
((h.scrollTop || b.scrollTop) /
((h.scrollHeight || b.scrollHeight) - h.clientHeight)) *
100
);
}
const scrollEvent = useCallback(() => {
setScrollPercentage(getScrollPercent());
}, []);
useEffect(() => {
window.addEventListener("scroll", scrollEvent);
return () => {
window.removeEventListener("scroll", scrollEvent);
};
}, [scrollEvent]);
return scrollPercentage;
}
useFetchWithSWR()
hooks/useFetchWithSWR.ts
import useSWR from "swr";
const fetcher = (...args) => fetch(...args).then((res) => res.json());
export default function useFetchWithSWR(url: string) {
const { data, error } = useSWR(url, fetcher);
return {
data,
isLoading: !error && !data,
isError: error,
} as {
data: any;
isLoading: boolean;
isError: any;
};
}
useShare()
hooks/useShare.ts
import { useEffect, useState } from "react";
function useShare() {
// state for share supports
const [isShareSupported, setIsShareSupported] = useState(false);
// checking if that exist or not
useEffect(() => {
setIsShareSupported(() => ("share" in navigator ? true : false));
}, []);
return { isShareSupported };
}
export default useShare;
useWindowLocation()
hooks/useWindowLocation.ts
import { useEffect, useState } from "react";
import { useRouter } from "next/router";
type URL = string;
export default function useWindowLocation() {
const [currentURL, setCurrentURL] = useState<URL>("");
const router = useRouter();
useEffect(() => {
setCurrentURL(window.location.href);
}, [router.asPath]);
return { currentURL };
}
useWindowSize()
hooks/useWindowSize.ts
import { useState, useEffect } from "react";
export default function useWindowSize() {
// Initialize state with undefined width/height so server and client renders match
const [windowSize, setWindowSize] = useState({
width: 0,
height: 0,
});
useEffect(() => {
// Handler to call on window resize
function handleResize() {
// Set window width/height to state
setWindowSize({
width: window.innerWidth,
height: window.innerHeight,
});
}
// Add event listener
window.addEventListener("resize", handleResize);
// Call handler right away so state gets updated with initial window size
handleResize();
// Remove event listener on cleanup
return () => window.removeEventListener("resize", handleResize);
}, []); // Empty array ensures that effect is only run on mount
return windowSize;
}