Search for a command to run...
Next.js 13.4에 도입된 App Router는 데이터 페칭 방식을 근본적으로 바꾸었습니다. 이제 React 서버 컴포넌트(RSC) 내에서 async/await를 사용하여 데이터를 직접 가져올 수 있습니다. TypeScript와 함께 사용하면 API 응답 데이터의 타입을 정의하여 더욱 안전하게 데이터를 다룰 수 있습니다.
별도의 useEffect나 getServerSideProps 없이, 컴포넌트 함수 자체를 async로 선언하고 내부에서 fetch를 호출하면 됩니다.
// app/users/page.tsx
// 1. API 응답 데이터에 대한 타입 정의
interface User {
id: number;
name: string;
username: string;
email: string;
}
async function getUsers(): Promise<User[]> {
const res = await fetch('[https://jsonplaceholder.typicode.com/users](https://jsonplaceholder.typicode.com/users)', {
// 2. Next.js 확장 fetch 옵션 (캐싱 제어)
next: { revalidate: 60 } // 60초마다 데이터 재검증
});
if (!res.ok) {
throw new Error('Failed to fetch data');
}
return res.json();
}
export default async function UsersPage() {
// 3. await를 사용하여 데이터 직접 호출
const users = await getUsers();
return (
<main>
<h1>Users</h1>
<ul>
{users.map((user) => (
<li key={user.id}>{user.name} (@{user.username})</li>
))}
</ul>
</main>
);
}
위 예제에서 User 인터페이스를 정의한 것이 핵심입니다.
getUsers 함수의 반환 타입을 Promise<User[]>로 명시하여, 이 함수가 User 객체 배열을 비동기적으로 반환한다는 것을 보장합니다.UsersPage 컴포넌트에서 users 변수는 User[] 타입으로 추론됩니다.users.map 콜백 함수 안의 user 객체는 User 타입이 되며, user.id, user.name과 같은 속성에 접근할 때 자동 완성이 지원되고 타입이 틀리면 즉시 에러가 발생합니다.만약 API 응답에 name 대신 fullName이라는 필드가 있었다면, user.name을 사용하려고 할 때 TypeScript가 "Property 'name' does not exist on type 'User'" 와 같은 오류를 표시해 줄 것입니다. 이는 런타임 에러를 개발 단계에서 미리 잡을 수 있게 해주는 강력한 기능입니다.
async/await를 사용해 직접 데이터를 가져옵니다.interface나 type을 반드시 정의하여 사용합니다.fetch의 캐싱 옵션(cache, next.revalidate)을 활용하여 데이터의 신선도를 제어합니다.이러한 패턴을 따르면, 서버와 클라이언트 간의 데이터 흐름이 명확해지고, 애플리케이션 전반의 데이터 무결성을 유지하는 데 큰 도움이 됩니다.