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

key 속성을 이용해 searchParams.q 가 변할 때도 트러거링될 수 있게 해줄 수 있어요.
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 을 통해 두 함수가 동시에 호출되게 해줍니다.