본문 바로가기

카테고리 없음

[트러블 슈팅] Next.js SSR 업데이트 기능 (새로고침 동작x)

반응형

 

발생한 오류 🔥

Next.js에서 클라이언트 측 라우팅을 위한 `Link` 컴포넌트를 사용하던 중, 내가 원하던 동작은 `SSR` 페이지로 이동할 때마다 데이터를 가져오는 것이었지만, 첫 번째 렌더링만 데이터를 가져오고 이후에는 router에 의해 캐싱이 돼서 새로운 데이터를 가져오지 못하는 문제가 있었습니다.

 

기존 코드

// app > layout.tsx

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body
        className={`${geistSans.variable} ${geistMono.variable} antialiased`}
      >
        <header>
          <Link href={"/"}>CSR</Link> |
          <Link href={"/isr"}>ISR</Link> |
          <Link href={"/ssr"}>SSR</Link> |
          <Link href={"/ssg"}>SSG</Link>
        </header>
        {children}
      </body>
    </html>
  );
}
// app > ssr > page.tsx

const ServerSideRenderingPage = async () => {
  const data: Post[] | undefined = await api.getPosts();
  console.log("ssr 렌더링 ",data);

  return <PostList posts={data} />;
};

export default ServerSideRenderingPage;

첫 번째 렌더링만 데이터 가져오기

 

해결 과정 🔎

시도 1

const NoCacheLink = ({
  href,
  children,
}: {
  href: string;
  children: React.ReactNode;
}) => {
  const router = useRouter();
  return (
    <Link href={href} onClick={() => {
      console.log('출력 될까')
      router.refresh()}}>
      {children}
    </Link>
  );
};

 

`NoCacheLink` 컴포넌트를 따로 만들어 `router.refresh()`를 사용해 주는 방법이었습니다.

 

 

여기서 문제점

onClick 핸들러가 실행되긴 하지만, console.log()만 출력되고 실제 Link의 기본 라우팅 동작이 먼저 실행되기 때문에 새로고침일 발생하지 않는 문제가 있었습니다.

 

그래서 refresh에 실행 타이밍을 Link에 의해 라우팅이 완료가 된 후 수행할 수 있도록 코드를 수정해주어야 했습니다.

 

해결 방법 ✨

수정된 코드

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body
        className={`${geistSans.variable} ${geistMono.variable} antialiased`}
      >
        <header>
          <Link href={"/"}>CSR</Link> |
          <Link href={"/isr"}>ISR</Link> |
          <NoCacheLink href="/ssr">SSR</NoCacheLink> |
          <Link href={"/ssg"}>SSG</Link>
        </header>
        {children}
      </body>
    </html>
  );
}
"use client";

const NoCacheLink = ({
  href,
  children,
  ...props
}: LinkProps & HTMLProps<HTMLAnchorElement>) => {
  const router = useRouter();
  const pathname = usePathname();

  useEffect(() => {
    if(pathname === href){
      console.log('출력')
      router.refresh();
    }
  }, [pathname]);

  return (
    <Link
      href={href}
      {...props}
    >
      {children}
    </Link>
  );
};

 

`usePahtname`으로 현재 경로를 추적해 `pathname` === `href`가 동일할 때마다 `router.refresh()`를 호출할 수 있도록 수정했습니다. 

 

수정 후 SSR 페이지 이동 시 데이터 패칭

 

수정한 결과, SSR 페이지 클릭 시 새로운 데이터를 가져오는 걸 확인할 수 있었습니다.

 

느낀 점❕

캐싱 메커니즘

Next.js는 클라이언트 측 라우팅이 기본적으로 성능 최적화를 염두해 페이지 이동 시 데이터를 캐싱하는 방식으로 동작하는 것을 알게 되었습니다.

 

그러나 성능적인 이점은 있지만 내가 원하는 것처럼 매번 새로운 데이터를 가져오는 동작을 구현하려면 캐싱 메커니즘을 적절히 제어해야 한다는 것을 깨닫게 되었습니다.

 

최적화 성능과 최신 데이터 간의 균형

최적화된 성능과 최신 데이터 간의 균형을 맞추는 것이 사용자 경험에 매우 중요한 역할을 한다는 걸 깨닫게 되었습니다.

 

빠른 반응 속도와 최신 정보 제공은 둘 다 중요한 요소이고 이러한 측면을 고려했을 때, 클라이언트 측 라우팅의 캐시 전략을 적절히 관리하는 게 중요하는 것을 알게 되었습니다.

 

 

이 방법도 맞는 방법인지는 고민을 더 해봐야겠습니다!

조언은 언제나 환영입니다!!

반응형