호텔 앱에서 무한 스크롤링을 적용하다 보니, 이전에 선택한 상품을 기억하지 못하여 다시 스크롤을 이동하는 번거로움을 해결하기 위해, 스크롤 복원(Scroll Restoration) 기능을 구현한 커스텀 훅으로, 스크롤 복원은 사용자가 이전 페이지로 돌아갔을 때 스크롤 위치를 이전 상태로 복원해주는 기능을 구현하는 데 사용됩니다.
라이브러리 등록
import { useCallback, useContext, useEffect, useRef } from "react";
import { Context } from "@COMPONENTS/provider/ScrollRestoreProvider";
import { useRouter } from "next/router";
debounce
함수 정의
const debounce = (callback: () => void, timeout = 100) => {
// 콜백 함수를 디바운스 처리하는 함수를 정의합니다.
let timer;
return () => {
clearTimeout(timer);
timer = setTimeout(() => {
callback();
}, timeout);
};
};
useScrollRestoration
커스텀 훅 정의
const useScrollRestoration = () => {
const router = useRouter();
const scrollRestoreContext = useContext(Context); // 스크롤 복원 Context
const restoreScroll = useRef<number>(); // 스크롤 위치를 저장하는 useRef
// 스크롤 이벤트를 처리하는 콜백 함수를 디바운스 처리
const event = useCallback(
debounce(() => scrollRestoreContext.setScrollData()),
[],
);
// 스크롤 위치를 복원
useEffect(() => {
restoreScroll.current = scrollRestoreContext.getScrollData();
window.addEventListener("scroll", event); // 스크롤 이벤트 리스너를 등록
return () => {
window.removeEventListener("scroll", event); // 컴포넌트가 언마운트될 때, 스크롤 이벤트 리스너를 제거
};
}, [router]);
// 스크롤 복원 데이터를 설정하는 함수를 정의
const setRestoreData = useCallback((data: any) => {
scrollRestoreContext.setRestoreData(data);
}, []);
// 스크롤 복원 데이터를 가져오는 함수를 정의
const getRestoreData = useCallback(() => scrollRestoreContext.getRestoreData(), []);
// 스크롤 위치를 이전 값으로 복원하는 함수를 정의
const scrollUpdate = useCallback(() => {
window.scrollTo(0, Number(restoreScroll.current));
}, []);
return {setRestoreData, getRestoreData, scrollUpdate};
};
scrollRestore
함수 정의
// 스크롤 데이터를 Context에 저장하는 로직
const scrollRestore = () => {
const scrollRestoreContext = useContext(Context);
const setRestoreData = useCallback((data: any) => {
scrollRestoreContext.setRestoreData(data);
}, []);
const getRestoreData = useCallback(() => scrollRestoreContext.getRestoreData(), []);
return {setRestoreData, getRestoreData};
};