현재 프론트엔드 개발자로서 웹 포트폴리오 사이트를 개발하고 있다. 나의 포트폴리오의 경우 한 페이지에 여러 섹션이 있고 오롯이 스크롤로만 섹션을 이동하는 구조다. 그렇다보니 뒤로가기 시에 최상단으로 이동하는 것에 있어서 비효율적인, 사용성 측면에서의 불편함을 느꼈다.
Projects 섹션에서 상세보기
버튼을 누르고, 상세 페이지에서 다시 목록으로 가기
버튼을 누를 시에 메인 페이지의 최상단으로 이동이 되었다. 이전 스크롤 위치인 Projects 섹션에 위치하도록 구현해 보자.
일반적으로 브라우저의 히스토리는 페이지의 URL만을 저장한다. 만약 페이지가 스크롤 위치 정보를 URL에 저장하지 않는다면, 브라우저는 이전 페이지의 스크롤 위치를 알 수 없다. (당연한 것) 이는 뒤로 가기를 눌렀을 때 페이지가 처음 로드된 위치로 돌아가는 현상을 발생시킬 수 있다. (당연한 것)
이를 위해서는 상세 페이지에서 이전 페이지의 스크롤 위치를 저장하는 것이 아니라, 상세 페이지로 이동하기 전에 이전 페이지의 스크롤 위치를 저장해야 한다.
상세보기
버튼을 클릭 -> 세션 스토리지에 현재 스크롤 위치를 저장해준다.const handleDetailNavigation = () => {
sessionStorage.setItem("scrollPosition", window.scrollY.toString());
};
<Link href={`/detail/${props.index}`}>
<S.DetailButton onClick={handleDetailNavigation}>상세보기</S.DetailButton>
</Link>
목록으로 가기
버튼을 클릭 -> 메인 페이지 컴포넌트에서 저장된 scrollPosition이 있다면, 해당 위치로 스크롤을 이동시킨다. useEffect(() => {
if (scrollPosition) {
requestAnimationFrame(() => {
window.scrollTo(0, parseInt(scrollPosition));
});
}
sessionStorage.removeItem("scrollPosition");
}, [scrollPosition]);
(여기서 requestAnimationFrame
콜백 함수는 스크롤 등의 이벤트를 최적화하기 위해 사용된다. 이는 불필요한 렌더링 작업을 줄이고, 애니메이션의 성능을 최적화한다고 한다!)
그러면
목록으로 가기
버튼 클릭 시router.back()
해주면, 이전 페이지의 최상단으로 이동하지 않고 이 전에 위치했던 스크롤 위치로 이동할 것이다!!! 끝!!!