혼자 적어보는 노트

[Next.js] Shallow: true 뒤로가기 시 데이터 패칭 본문

NextJS

[Next.js] Shallow: true 뒤로가기 시 데이터 패칭

jinist 2022. 8. 31. 22:41

 

 

 

이전 프로젝트에서 CSR로만 구성되어 있던 유저 페이지를 SSR을 통해 일부 데이터를 미리 받는 방식으로

변경을 하기로 했다.

 

export const getServerSideProps = async (context: NextPageContext) => {
  const { id } = context.query;
  const userId = Number(id);

  if (Number.isNaN(userId)) {
    return {
      notFound: true
    };
  }

  try {
    const user = await UserApi.getUser(userId);
    return {
      props: { user, userId }
    };
  } catch (e) {
    return {
      notFound: true
    };
  }
};

이렇게 미리 받으면 페이지를 렌더하기 전에 서버에 일치하는 값이 없을 경우

404로 보내버릴 수 있고 데이터를 미리 받아서 head의 title에도 넣을 수 있었다.

 

하지만,,

 

 

❗ 문제상황

다른 유저의 페이지에서 로그인한 유저의 페이지로 이동하는 것은 정상적으로 이동이 되지만
뒤로가기를 할 경우 route가 바뀜에도 불구하고 다른 유저의 데이터를 보여주지 않는 문제가 발생했다.

 

 

왜??!

추측해본 바로는 유저 페이지의 Tab을 유지시키기 위해

유저페이지에 접근했을 때 router.replace를 통해 tab에 대한 active값을 query로 담아주고 있는데
이 부분 때문에 뒤로가기 시 인지를 못하는것 같았다.

 

  const replaceRoute = (query: UserInfoTab) => {
    router.replace(
      { pathname: '/userinfo/[id]', query: { tab: query } },
      `/userinfo/${userId}?tab=${query}`,
      {
        shallow: true
      }
    );
  };

shallow 옵션을 빼면 정상적으로 작동이 되지만

현재 _app.tsx에 shallow가 아닌 route이동 시 로딩 스피너를 보여주는 코드를 작성해놓았고

유저 페이지에 접근하자마자 replace를 하고 있기 때문에 shallow 옵션을 빼버린다면

무한 렌더링이 생기기 때문에😢 일단 다른 방법으로 해결을 해보기로 했다.

 

좀 더 자세히 테스트를 해 보니

shallow로 replace한 마이페이지 url에서 shallow로 replace한 다른 유저 페이지 url로 이동할 경우에

getServerSideProps가 실행되지 않는 것으로 확인되었다.

 

 

✅문제 해결

뒤로가기 이벤트가 발생했을 때 serversideProps를 다시 실행시킬 순 없을까 검색 하다가

정말 우연히 발견한 글을 읽다가 해결했다.

 

 router.beforePopState(({ as, options }) => {
      if (options.shallow) {
        router.replace(as);
        return false;
      }
      return true;
    });

뒤로가기/앞으로가기 시 option이 shallow일 경우 popstate를 하지 않고 다시 replace를 해줌으로써

원하는대로 동작하게 되었다.🙌

❗ 여기서 as는 뒤로가기/앞으로가기를 통해 진입하는 페이지의 경로가 담긴다.

 

 

같은 페이지를 이동하는데에 있어서 처리해줄 코드들이 조금 있기는 했지만

위 코드가 힌트가 되어 나머지는 금방 처리할 수 있었다

Comments