Next.js에서 loading.tsx는 로딩 UI를 제공하는 컴포넌트 파일로, App Router (app/ 디렉터리)에서 동적 데이터를 가져올 때 자동으로 사용됩니다.
이를 활용하면 데이터 로딩 중에도 부드러운 사용자 경험(UX)을 제공할 수 있습니다.
loading.tsx의 역할
- 자동 로딩 UI 제공: Next.js가 데이터를 불러오는 동안 loading.tsx가 자동으로 렌더링됩니다.
- 서버 및 클라이언트 컴포넌트에서 사용 가능: 서버에서 데이터를 가져오거나, 클라이언트에서 Suspense를 사용할 때 적용할 수 있습니다.
- 레이아웃(layout.tsx)에도 적용 가능: 특정 경로에 대한 전체 로딩 UI를 설정할 수도 있습니다.
특정 경로에서 loading.tsx를 생성하면, 해당 경로가 로딩 중일 때 자동으로 표시됩니다.
예시 /dashboard의 로딩 UI 추가
app/dashboard/loading.tsx
export default function Loading() {
return <p>Loading Dashboard...</p>;
}
- /dashboard 페이지가 서버에서 데이터를 가져오는 동안 "Loading Dashboard..."가 표시됩니다.
loading.tsx가 실행되는 시점
- 서버에서 데이터를 패칭하는 동안 (fetch(), 데이터베이스 요청 등)
- Suspense를 사용할 때 (React.lazy, 클라이언트 사이드 컴포넌트 등)
- 레이아웃(layout.tsx)이 적용된 하위 페이지가 로딩될 때
- 즉, 특정 페이지가 완전히 렌더링되기 전에 Next.js가 자동으로 loading.tsx를 보여줍니다.
서버 데이터 패칭과 로딩 UI 적용하기
app/dashboard/page.tsx
export default async function DashboardPage() {
const data = await fetch("https://jsonplaceholder.typicode.com/posts")
.then((res) => res.json());
return (
<div>
<h1>Dashboard</h1>
<ul>
{data.slice(0, 5).map((post: any) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</div>
);
}
- fetch()를 사용하여 데이터를 가져오는 동안 /dashboard/loading.tsx가 먼저 렌더링됩니다.
레이아웃(layout.tsx)과 함께 사용하기
loading.tsx는 특정 경로(app/dashboard/)의 모든 하위 페이지에도 적용할 수 있습니다.
app/dashboard/layout.tsx
export default function DashboardLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<div>
<h1>Dashboard Layout</h1>
{children}
</div>
);
}
app/dashboard/loading.tsx
export default function Loading() {
return <p>🔥 Loading Dashboard Content...</p>;
}
- 이제 /dashboard/* 경로의 모든 페이지가 로딩될 때 loading.tsx가 표시됩니다.
Suspense와 함께 사용하기 (클라이언트 컴포넌트)
Next.js의 Suspense를 활용하면 클라이언트 사이드에서도 loading.tsx 대신 별도의 로딩 UI를 설정할 수 있습니다.
app/dashboard/page.tsx
import { Suspense } from "react";
import DashboardContent from "./DashboardContent";
export default function DashboardPage() {
return (
<Suspense fallback={<p>⏳ Loading Content...</p>}>
<DashboardContent />
</Suspense>
);
}
app/dashboard/DashboardContent.tsx
export default async function DashboardContent() {
const data = await fetch("https://jsonplaceholder.typicode.com/posts").then((res) => res.json());
return (
<ul>
{data.slice(0, 5).map((post: any) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}
- Suspense의 fallback을 설정하면, loading.tsx가 아니라 특정 컴포넌트의 로딩 UI를 지정할 수도 있습니다.
'개발 공부 > React' 카테고리의 다른 글
| React Virtual DOM (0) | 2025.04.09 |
|---|---|
| React 함수형 컴포넌트 vs 클래스형 컴포넌트 (0) | 2025.04.06 |
| React Focus Lock (0) | 2025.03.22 |
| Next.js LoginForm (0) | 2025.03.19 |
| Next.js Metadata (0) | 2025.03.10 |