으니의 개발로그

[Next.js] 브라우저 뒤로가기 동작을 제어하고 싶을때 (feat. router.beforePopState) 본문

Front-end/Next.js

[Next.js] 브라우저 뒤로가기 동작을 제어하고 싶을때 (feat. router.beforePopState)

아잉으니야 2023. 7. 27. 13:29

What I wanted

회원탈퇴 페이지에서 비밀번호 인증을 한 뒤 페이지 내에 있는 링크를 통해 다른 페이지로 이동했다가 뒤로가기 동작으로 회원탈퇴 페이지에 돌아왔을 시 비밀번호 인증 된 페이지를 보여주고 싶음

 

해결방법

회원탈퇴 페이지에서 A페이지로 이동할때 isCheck=true 라는 파라미터를 넘겨주고 뒤로가기 클릭 시 그 때 받은 파라미터를 다시 넘겨주는 것으로 해결했다.

밑의 코드는 A페이지에 작성한 코드이다.

// 회원탈퇴 페이지
const onClickGoAPage = useCallback(
  () =>
    router.push(
      {
        pathname: '/a',
        query: { isChecked: true },
      },
      '/a',
    ),
  [router],
);

// A 페이지
useEffect(() => {
  router.beforePopState(({ as }) => {
    if (as === '/secession') {
      void router.replace({ pathname: as, query: router.query }, as);
      return false;
    }
    return true;
  });
  return () => router.beforePopState(() => true);
}, [router]);

뒤로 갈 페이지가 회원탈퇴 페이지(/secession) 일 때만 router.replace를 통해 query에 router.query를 넘겨주는 방식으로 해결했다.

 

그렇다면 여기서 사용 된 beforePopState는 무엇일까?

router.beforePopState(cb)

뒤로가기가 동작하기 전에 무언가를 하고 싶을 때 사용한다.

false를 리턴하면 아무런 동작이 일어나지 않고 true를 리턴하면 원래의 뒤로가기 동작이 실행된다.

 

beforePopState 동작 시점

router.beforePopState를 사용하면서 한가지 이상하다 생각되는 동작이 있었다. 예를들어 A페이지 > B페이지 > C페이지(현재페이지) 일때 뒤로가기 동작시 B페이지로 router.replace를 실행하면 B페이지에서 뒤로가기 했을때 A페이지로 가는 것이다. 내가 생각했을때는 C페이지에서 B페이지로 router.replace했으니깐 history 스택이 A페이지 > B페이지 > B페이지 로 쌓여있어야 하는데 실제로는 A페이지 > B페이지 로 쌓여져있었다. 그래서 C페이지에서 router.beforePopState에서 history를 console.log를 찍어보니 B페이지가 저장되어있었다.

console.log를 보고 알게 된 점은 router.beforePopState는 history 스택에서 현재 페이지 정보가 제거된 이후에 동작한다는 것이다. 브라우저의 뒤로가기 버튼을 클릭하면 router.beforePopState 콜백 함수가 호출된다. 이때, history 스택에서 가장 위에 있는 이전 페이지의 정보는 이미 제거되고, 현재 페이지의 정보만 남아있다. 그리고 이 시점에서 router.beforePopState가 실행된다.

그래서 C페이지의 정보가 제거된 뒤 B페이지에서 router.replace가 실행되기 때문에 A페이지 > B페이지 로 스택이 쌓이는 것이다.

만약, C페이지에서 B페이지가 아닌 A페이지로 router.replace를 해줬다면 A페이지 > A페이지 로 스택이 쌓였을 것이고, D페이지로 router.replace를 해줬다면 A페이지 > D페이지로 스택이 쌓였을 것이다.

 

 

참고자료

https://nextjs.org/docs/pages/api-reference/functions/use-router#routerbeforepopstate

 

Functions: useRouter | Next.js

Using Pages Router Features available in /pages

nextjs.org