Nextjs에서 리스트 페이지 뒤로가기 버튼 구현

이재진·2024년 4월 11일

모애프로젝트

목록 보기
16/16

리스트페이지에서 게시글을 들어갔다가 다시 돌아오면, 페이지 상단으로 올라가 있는 문제가 생겼다... 이 부분을 해결하고자, 방법을 찾아봄

문제

게시판에서 게시물로 들어갔다가 나오면, 무한 스크롤 특성상, 해당 위치가 저장되어서 다시 이어서 게시글을 볼 수 있게해야 하는데, 최상단으로 이동해서 페이지의 위치를 다시 돌아올 수 있는 방법을 찾아보았다.

생각한 방법

localStorage를 활용하는 방법이다. 내가 페이지에 들어갔을 때, localStorage에 저장하면 다시 해당 페이지로 돌아왔을 때, localStorage에서 값을 받아서 사용하면 될 것이라고 생각했다.

적용

  const handleRouteChange = useCallback((e: any) => {
    localStorage.setItem(
      `__next_scroll_back`,
      JSON.stringify({
        x: 0,
        y: window.scrollY.toString(),
      }),
    );
  }, []);

  //router발생시 스크롤 위치 저장
  useEffect(() => {
    router.events.on('routeChangeStart', handleRouteChange);
    window.addEventListener('beforeunload', handleRouteChange);
    return () => {
      router.events.off('routeChangeStart', handleRouteChange);
      window.removeEventListener('beforeunload', handleRouteChange);
    };
  }, [router.events]);

  //스크롤 위치 복원 & session비우기
  useEffect(() => {
    const temp = JSON.parse(
      localStorage.getItem(`__next_scroll_back`) as string,
    );
    temp && setTimeout(() => window.scrollTo(0, temp.y), 0);
  }, []);

페이지를 넘어갈 때 route가 바뀌는 것을 이용해서 route.evnet가 동작한다면, localStorage에 값을 저장해 주도록 했다.

문제 발생

이렇게 작성을 해도, 내가 생각한 것 처럼 스크롤이 유지가 되는게 아닌, 상단으로 이동되는 것이었다.

이 이유에 대해서 찾아보니, next에서 제공하는 history.scrollRestoration이 있는데, 이게 auto가 기본 default값으로 지정되어 있어서 그런 것이라고 한다.
참고블로그

그래서 코드 위에 해당 코드를 삽입하여서 해결했다.

  // 스크롤 수동으로 조정 설정
  useEffect(() => {
    if (
      'scrollRestoration' in history &&
      history.scrollRestoration !== 'manual'
    ) {
      history.scrollRestoration = 'manual';
    }
  }, []);

오케이 이제 스크롤이 잘 동작한다.

문제 발생222

창을 닫고 페이지를 나갔다가 들어오면, 해당 스크롤 위치로 자동 이동한다는 문제가 발생했다.
아마 localStorage는 브라우저를 종료해도 해당 정보가 저장되어서 다음에도 사용을 할 수 있다는 것 이었다.
그래서 localStoragesessionStorage로 바꿔서 작성하니 브라우저를 나갓다가 들어오면 정상적으로 상단에 스크롤이 위치에 있었다.

리펙토링

이게 실제로 적용해 보고 나니깐 돌아올 때, 리스트를 불러서 깜빡이는 현상이 발생하는 부분이 있었다. 이 부분을 ssr을 활용해서 진행하면 깜빡임 없이 진행 할 수 있을 것 같다는 생각을 했다.

스크롤을 저장하는 기능을 여러부분에서 사용될 수 있어서, hook으로 만들어서 사용해도 좋을 것 같다는 생각을 했다.

profile
소통하는 개발자

0개의 댓글