스트리밍(Streaming)과 로딩, 에러 상태 관리
App Router에서는 React Suspense와 Error Boundary가 파일 시스템에 기본 내장되어 있습니다.
loading.tsx를 추가하면 서버 컴포넌트가 데이터를 패치하는 동안 스켈레톤 UI를 스트리밍(Streaming)하여 사용자 경험(UX)을 극대화합니다. error.tsx는 특정 컴포넌트 트리에 에러가 발생했을 때 전체 페이지가 다운되는 것을 막고, 해당 부분만 에러 UI로 대체하며 복구(Recover) 버튼을 제공할 수 있습니다.
// ==========================================
// 📂 app/dashboard/error.tsx
// ==========================================
'use client' // Error components must be Client Components
import { useEffect } from 'react'
export default function Error({
error,
reset,
}: {
error: Error & { digest?: string }
reset: () => void
}) {
useEffect(() => {
// 외부 에러 트래킹 서비스(Sentry 등)로 로깅할 수 있습니다.
console.error(error)
}, [error])
return (
<div className="p-4 bg-red-500/10 border border-red-500 rounded-lg flex flex-col items-center">
<h2 className="text-red-500 font-bold mb-4">데이터를 불러오는 중 문제가 발생했습니다!</h2>
<button
onClick={() => reset()} // 컴포넌트 재렌더링 시도 (Recover)
className="px-4 py-2 bg-red-600 text-white rounded hover:bg-red-700 transition"
>
다시 시도하기
</button>
</div>
)
}
// ==========================================
// 📂 app/dashboard/loading.tsx
// ==========================================
export default function Loading() {
// 실제 페이지(page.tsx)가 렌더링되기 전 즉시 브라우저로 스트리밍됩니다.
return (
<div className="p-4 space-y-4 animate-pulse">
<div className="h-8 bg-slate-700 rounded w-1/4"></div>
<div className="h-32 bg-slate-700 rounded w-full"></div>
<div className="h-32 bg-slate-700 rounded w-full"></div>
</div>
)
}