Custom Hook in React (TypeScript)

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;
}