한입 -5

천주아·2024년 12월 6일

스트리밍(Streaming)

  • 서버에서 클라이언트로 어떤 데이터를 보낼 때, 데이터 크기가 너무 크거나 데이터 크기가 커서 빠르게 전송하기 어려울 때 데이터를 잘게 쪼개서 하나하나씩 클라이언트에 보내는 기술
  • 랜더링하는데에 오래걸리더라도 로딩바 같은 대체 UI를 보여줌으로써 사용자의 불편을 줄인다.
  • Dynamic Page 에 적용하는 것이 올바르다.(Static Page의 경우 렌더링할 때 모든 비동기 작업을 끝내기 때문)
  • 페이지 스트리밍보다는, suspense를 사용하는 컴포넌트 스트리밍이 조금 더 유용하게 쓰인다.

페이지 스트리밍

  • 적용하고자 하는 'page.tsx' 파일이 존재하는 폴더 내에 'loading.tsx' 파일을 생성해 코드를 작성한다.
// loading.tsx
export default function Loading() {
  return <div>Loading...</div>
}

페이지 스트리밍을 사용할 때 주의할 점

  1. 해당 파일과 같은 폴더 내에 있는 페이지뿐만 아니라, 해당 경로를 포함하는 모든 페이지에서 적용된다.(Layout과 비슷)
  2. 비동기(async)로 제공하는 페이지에만 적용된다.
  3. page 파일에만 적용이 가능하다.
  4. 쿼리스트링만 변경될 때에는 적용되지 않는다.

컴포넌트 스트리밍

  • 컴포넌트로 비동기 함수를 감싸주면 해당 함수를 미완성, 로딩 상태로 남겨놓는 것이다.
  • 쿼리스트링만 변경될 때에는 적용되지 않는다.
    → 해결법: key 값을 props로 두어 key 값이 변경될 때마다 스트리밍이 적용되도록 함.
  • 하나의 페이지 내에서 여러 비동기 함수들을 스트리밍할 때 가장 유용하다
// page.tsx
return (
    <Suspense key={q || ""} fallback={<div>Loading...</div>}>
      <SearchResult q={q || ""} />
    </Suspense>
);

에러핸들링

  • 클라이언트 컴포넌트로 설정(서버 컴포넌트든, 클라이언트 컴포넌트든 실행이 되기위해)
  • 적용하고싶은 파일과 같은 경로에 파일을 작성하면 된다.
'use client';

import { useRouter } from "next/navigation";
import { useEffect } from "react";

export default function Error({ 
  error, 
  reset
}: { 
  error: Error; 
  reset:() => void 
}) {
  const router = useRouter();

  useEffect(() => {
    console.log(error.message);
  }, [error])
  

  return <div>
    <h3>오류가 발생했습니다.</h3>
    <button onClick={() => {
      startTransition(() => {
        router.refresh(); // 현재 페이지에 필요한 서버 컴포넌트를 다시 불러옴 
        reset(); // 에러 상태를 초기화, 컴포넌트들을 다시 렌더링
      });
      }}>다시 시도</button>
  </div>
}
profile
프론트엔드 엔지니어

0개의 댓글