[Next.js]App Router 스트리밍

ssookk·2026년 2월 24일

nextjs

목록 보기
6/7

큰 데이터를 잘라 연속적으로 보내는 것
스트리밍을 이용하게 되면 일단 뭐라도 빠르게 보여줄 수 있기에
오래 걸리는 컴포넌트의 렌더링을 사용자가 좀 더 좋은 환경에서 기다릴 수 있게 해줄 수 있습니다.
비유를 들자면, 메인 디쉬가 나오기 전에 밑반찬을 식당에서 미리 주는 상황이에요.
Dynamic Page에서 자주 사용됩니다. -> 데이터를 가져올 때 시간이 걸리는 상황!

페이지 스트리밍

  1. loading.tsx는 하위의 요소들에 적용된다.(마치 layout.tsx 같이)
  2. async가 아닌 page 컴포넌트들은 loading.tsx가 존재한다고 하더라도 스트리밍 되지 않는다.
  3. 페이지 컴포넌트에만 스트리밍 기능이 지원된다. 페이지 컴포넌트 외에는 Suspense 를 이용한다.
  4. 브라우저에서 쿼리 스트링이 변경될 때에는 트리거링 되지 않는다.
    ex. / 페이지 -> ...?q=hello 페이지로 넘어갈 땐 트리거링 됨
    ex. ...?q=hello-> ...?q=hi 트리거링 되지 않음, 쿼리 스트링만 변경될 때.

컴포넌트 스트리밍

Suspense 이용하기(권장)

페이지 컴포넌트 외의 컴포넌트에 스트리밍을 적용하려면 Suspense를 이용하면 됩니다.
또한 쿼리 스트링이 변경될 때 트리거링 되지 않을 때도 Suspense를 이용하면 해결할 수 있어요.

key 속성을 이용해 searchParams.q 가 변할 때도 트러거링될 수 있게 해줄 수 있어요.

Error 처리하기

error.tsx를 만들어요.

"use client"

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


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

    useEffect(()=> {
        console.error(error.message);
    }, [error])
    return(
        <div>
            <h3>오류가 발생했습니다.</h3>
            <button onClick={()=> {
                // reset
                startTransition(()=> {
                     router.refresh(); // Next 서버에게 서버 컴퍼넌트만 새롭게 렌더링
                // 현재 페이지에 필요한 서버 컴퍼넌트들을 다시 불러옴
                reset(); // reset은 클라이언트 컴퍼넌트만!
                // reset 함수 : 에러 상태를 초기화, 컴포넌트들을 다시 렌더링
                // router.refresh만 할 경우 에러 상태가 초기화되지 않음.
                })
               
                }}>다시 시도</button>
        </div>
    )
}

router.refresh() : Next 서버에게 서버 컴포넌트만 새롭게 렌더링하게 합니다. 현재 페이지에 필요한 서버 컴포넌트들을 다시 불러오게 합니다.
reset() : 클라이언트 컴포넌트만 렌더링합니다.
startTransition을 사용한 이유 :
사용하지 않을 경우, router.refresh가 비동기로 동작하기에 refresh가 동작하기 전 reset이 동작해 서버 컴포넌트가 불러오지 않기 때문이에요. startTransition 을 통해 두 함수가 동시에 호출되게 해줍니다.

0개의 댓글