개발새발 로그

NextJS app router에서 router.back()를 사용할 때 알면 좋은 것 본문

React

NextJS app router에서 router.back()를 사용할 때 알면 좋은 것

이즈흐 2024. 3. 26. 23:03

NextJs app router를 사용하면서 문제가 있었다.

 

메인페이지와 경매상세페이지 라는 곳이 있었고 

메인페이지에서 어떤 경매를 클릭하고 경매를 들어갈 수 있었다.

근데 여기서 문제가 있었다. 
경매 상세 페이지에서 새로고침을 하고 헤더에 있는 뒤로가기 키를 누르면 아래와 같은 에러가 마구 쏟아졌다.

Uncaught Error: async/await is not yet supported in Client Components, 
only Server Components. This error is often caused by accidentally adding 'use client' to a module that was originally written for the server.

오류에서는 async/await가 클라이언트 컴포넌트에서 사용됐다고 한다.

 

근데 나는 async/await는 무조건 서버컴포넌트에서만 사용하고 있었다.

 그리고 애초에 async/await는 클라이언트 컴포넌트에 쓰면 에러가 뜬다.

 

그래서 나는 다시 생각해보았다.

현재 async/await가 쓰인 곳은 메인페이지다.

메인페이지의 코드는 아래와 같다.

const MainPage = async () => {
  const queryClient = new QueryClient();

  const user = queryClient.getQueryData<CheckLoginUserResponse>(["user"]);
  const address = user ? user.address : { si: "", gu: "", dong: "" };
  console.log("나는 하위 page.tsx의 user 상태 : " + user?.userId);

  await queryClient.prefetchQuery({
    queryKey: ["auction", "bookmark", address],
    queryFn: () => getSortedBookMarks({ address })
  });
  await queryClient.prefetchQuery({
    queryKey: ["auction", "recently", address],
    queryFn: () => getSortedRecentlyCreated({ address })
  });
  await queryClient.prefetchQuery({
    queryKey: ["auction", "deadline", address],
    queryFn: () => getSortedDeadLine({ address })
  });
  await queryClient.prefetchQuery({
    queryKey: ["auction", "bids", address],
    queryFn: () => getSortedBids({ address })
  });
  await queryClient.prefetchQuery({
    queryKey: ["auction", "category"],
    queryFn: getSortedCategory
  });
  const dehydratedState = dehydrate(queryClient);

  return (
    <section className="px-4">
      <HydrationBoundary state={dehydratedState}>
        <MainContentSection
          userSi={address.si}
          userGu={address.gu}
          userDong={address.dong}
          user={user ? user : null}
        />
      </HydrationBoundary>
    </section>
  );
};
export default MainPage;

 

이렇게 async/await를 쓰고있다.

 

여기서 생각이 든다.

왜 router.back()으로 뒤로갔는데 갑자기 이런 오류가 생기는 것일까?

일단 router.back()이 무슨 명령어인지 생각해보자

router.back()은 Next에서 클라이언트 사이드에서 동작하도록 하는 명령어다.

근데 만약 새로고침을 했다면 이전에 파싱했던 html들은 사라진다.

그리고 router.back()으로 메인페이지 이동을 하면 CSR에서 동작하는 것이기 떄문에 (Link나 뒤로가기)

일시적으로 데이터가 없을 것이다.

그러면 MainPage에 있던 async.awati를 실행하게 되고,

오류에서 클라이언트 사이드에서는 async/await를 사용할 수 없다고 뜨는 것이다.

 

그래서 CSR로 이동해도 SSR을 해서 async/await를 사용할 수 있도록 Loading을 보여줘서 데이터를 받아올 수 있도록 해야했다. 즉 Suspense같은 것이 필요했다.

근데 Next에서는 loading.tsx를 지원하고 있다.

그래서 loading.tsx를 사용해서 CSR로 메인페이지로 이동이 되더라도 다시 SSR로 데이터 요청을 할 수 있도록 loaidng을 보여주고 데이터를 받아와서 CSR로 넘어가도록 해야한다.

 

사실 위 이유는 정확하지 않다.

내가 추론한 이유이므로 레퍼런스를 더 찾아보고 수정할 것이다.

 

728x90
반응형
LIST