React custom hooks for later use
April 02, 2021
Table
useScroll
Return current user’s scroll position and direction.
import { useState, useEffect } from "react";
type StateType = {
lastScrollTop: number;
bodyOffset: DOMRect;
scrollY: number;
scrollX: number;
scrollDirection: "down" | "up" | "";
};
export const useScroll = () => {
const [state, setState] = useState<StateType>({
lastScrollTop: 0,
bodyOffset: document.body.getBoundingClientRect(),
scrollY: document.body.getBoundingClientRect().top,
scrollX: document.body.getBoundingClientRect().left,
scrollDirection: "",
});
useEffect(() => {
const handleScroll = () => {
setState((prevState) => {
const prevLastScrollTop = prevState.lastScrollTop;
const bodyOffset = document.body.getBoundingClientRect();
return {
bodyOffset,
scrollY: -bodyOffset.top,
scrollX: bodyOffset.left,
scrollDirection: prevLastScrollTop > -bodyOffset.top ? "up" : "down",
lastScrollTop: -bodyOffset.top,
};
});
};
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
}, []);
return {
scrollY: state.scrollY,
scrollX: state.scrollX,
scrollDirection: state.scrollDirection,
};
};
export default useScroll;
useWindowSize
Return current user’s browser window size.
import { useState, useEffect } from "react";
type WindowSizeType = {
width: number;
height: number;
};
const useWindowSize = () => {
const [windowSize, setWindowSize] = useState<WindowSizeType>({
width: 0,
height: 0,
});
useEffect(() => {
const handleResize = () => {
setWindowSize({
width: window.innerWidth,
height: window.innerHeight,
});
};
handleResize();
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
return windowSize;
};
export default useWindowSize;
useScreen
An extension of `useWindowSize()` hook, this one returns which screen size user is in.
import { useEffect, useState } from "react";
import { useTheme } from "styled-components";
import useWindowSize from "./useWindowSize";
type ScreenType = {
isSmall: boolean;
isMedium: boolean;
isLarge: boolean;
};
const parseSize = (breakpoint: string): number => {
return parseInt(breakpoint.replace("px", ""));
};
const useScreen = () => {
const theme = useTheme();
const { width } = useWindowSize();
const [screen, setScreen] = useState<ScreenType>({
isSmall: false,
isMedium: false,
isLarge: false,
});
useEffect(() => {
if (width < parseSize(theme.breakpoint.sm)) {
setScreen({
isSmall: true,
isMedium: false,
isLarge: false,
});
} else if (width < parseSize(theme.breakpoint.md)) {
setScreen({
isSmall: false,
isMedium: true,
isLarge: false,
});
} else {
setScreen({
isSmall: false,
isMedium: false,
isLarge: true,
});
}
}, [width, theme]);
return screen;
};
export default useScreen;
useStateWithSessionStorage
Use state to get and set Session Storage values.
const useStateWithSessionStorage = (sessionStorageKey: string) => {
const [value, setValue] = useState<string>(
sessionStorage.getItem(sessionStorageKey) || ""
);
useEffect(() => {
sessionStorage.setItem(sessionStorageKey, value);
}, [value, sessionStorageKey]);
return [value, setValue] as const;
};
export default useStateWithSessionStorage;