#3.0 Introduction
-Movie API
https://nomad-movies.nomadcoders.workers.dev
-JSON Viewer (구글 확장 프로그램)
https://chromewebstore.google.com/detail/json-viewer/gbmdgpbipfallnflgajpaliibnhdgobh
React에서 하는것처럼 fetch를 해보고난 다음에 Next.js에서 하는 fetch로 해본다. 두개를 비교.
#3.1 Client Side
로딩 직접 구현, metadata 못씀, fetch로 렌더링 일어남 등 client에서 데이터를 가져올 때 어떻게 되는지를 되새겨본다.
'use client';
import { useEffect, useState } from 'react';
export default function Page() {
const [isLoading, setIsLoading] = useState(true);
const [movies, setMovies] = useState([]);
const getMovies = async () => {
const response = fetch('https://nomad-movies.nomadcoders.workers.dev/movies');
const json = await (await response).json();
setMovies(json);
};
useEffect(() => {
getMovies();
setIsLoading(false);
}, []);
return (
<div>
<div>{isLoading ? 'Loading...' : JSON.stringify(movies)}</div>
</div>
);
}
#3.2 Server Side
export const metadata = {
title: 'Home',
};
const URL = 'https://nomad-movies.nomadcoders.workers.dev/movies';
async function getMovies() {
await new Promise(resolve => setTimeout(resolve, 5000));
const response = await fetch(URL);
const json = await response.json();
return json;
}
export default async function HomePage() {
const movies = await getMovies();
return <div>{JSON.stringify(movies)}</div>;
}
-fetch
Next.js는 기본 웹 fetch() API를 확장하여 서버의 각 요청이 자체 영구 캐싱 의미를 설정할 수 있도록 한다.
-Error Lens
VSCode에서 오류, 경고 및 기타 언어 진단을 강조하여 표시해주는 익스텐션이다.
#3.3 Loading Components
-Loading UI and Streaming
특수 파일 loading.js는 React Suspense를 사용하여 의미 있는 로딩 UI를 만드는 데 도움이 된다.
이 규칙을 사용하면 route 세그먼트의 콘텐츠가 로드되는 동안 서버에서 즉시 로딩 상태를 표시할 수 있다. 렌더링이 완료되면 새 콘텐츠가 자동으로 교체된다.
즉시 로딩 상태는 탐색 시 즉시 표시되는 대체 UI이다. 스켈레톤, 스피너 등 로딩 표시기나 표지 사진, 제목 등 미래 화면의 작지만 의미 있는 부분을 미리 렌더링할 수 있다.
이름은 반드시 loading이여야하고, page파일 옆에 위치해야만 한다.
#3.4 Parallel Requests
-Promise.all()
Promise.all()는 자바스크립트에서 여러 비동기 작업을 동시에 실행하고, 모든 작업이 완료될 때까지 기다렸다가 결과를 배열 형태로 반환하는 함수이다. 쉽게 말해, 여러 Promise를 모두 이행할 때까지 기다린 후, 그 결과를 한꺼번에 받아볼 수 있게 해준다.
Promise.all()은 하나라도 reject되면 전체가 reject되므로 오류 처리를 잘 해준다면 여러 Promise의 비동기 처리를 할 때 정말 유용하게 사용이 가능하다.
import { API_URL } from '../../../(home)/page';
async function getMovie(id: string) {
console.log(`Fetching movies: ${Date.now()}`);
await new Promise(resolve => setTimeout(resolve, 5000));
const response = await fetch(`${API_URL}/${id}`);
return response.json();
}
async function getVideos(id: string) {
console.log(`Fetching videos: ${Date.now()}`);
await new Promise(resolve => setTimeout(resolve, 5000));
const response = await fetch(`${API_URL}/${id}/videos`);
return response.json();
}
export default async function MovieDetail({ params: { id } }: { params: { id: string } }) {
const [movie, videos] = await Promise.all([getMovie(id), getVideos(id)]);
return <h1>{movie.title}</h1>;
}
병렬적으로 fetch하는 방법 중 하나이다. 다른 방법 중 하나는 다음에 배우는 suspense이다.
#3.5 Suspense
import { Suspense } from 'react';
import MovieInfo from '../../../../components/movie-info';
import MovieVideos from '../../../../components/movie-videos';
export default async function MovieDetail({ params: { id } }: { params: { id: string } }) {
return (
<div>
<h3>Movie detail page</h3>
<Suspense fallback={<h1>Loading movie info</h1>}>
<MovieInfo id={id} />
</Suspense>
<Suspense fallback={<h1>Loading movie videos</h1>}>
<MovieVideos id={id} />
</Suspense>
</div>
);
}
-nextjs15부터는 기본 캐싱이 안된다. 옵션을 넣어 줘야 캐싱이 된다.
방법1. next.config.ts파일 추가
const nextConfig = {
experimental: {
staleTimes: {
dynamic: 30,
},
},
};
module.exports = nextConfig;
방법2. typescript 5.1.3버전 이상, @types/react 18.2.8버전 이상 설치. @types/react가 없으므로 npm i-D @types/react 로 설치하기.
방법3. 컴포넌트 위에 주석 {/* @ts-expect-error Async Server Component */} 추가하기
{/* @ts-expect-error Async Server Component */}
< MovieInfo id={id} / >
{/* @ts-expect-error Async Server Component */}
< MovieVideos id={id} / >
캐싱을 확인하려면 fetch의 두 번째 인자의 cache옵션을 'force-cache'로 바꿔줘야한다.
const response = await fetch(`${API_URL}/${movieId}`, {
cache: "force-cache",
});
Page 단위 로딩 => loading.tsx
서버 컴포넌트 단위 로딩 => Suspense
#3.6 Recap
#3.7 Error Handling
-error.js
error 파일을 사용하면 예기치 않은 런타임 오류를 처리하고 대체 UI를 표시할 수 있다.
error.js는 React Error Boundary에서 라우트 세그먼트와 중첩된 자식을 래핑한다.
바운더리 내에서 오류가 발생하면 오류 컴포넌트가 대체 UI로 표시된다.
-Global Error
global-error.js를 사용하여 루트 레이아웃이나 템플릿의 오류를 처리할 수 있다.
-Error Handling
ㄴ
-ErrorBoundary
ㄴ
#3.8 Conclusions
'노마드코더10주챌린지' 카테고리의 다른 글
NextJS - Deployment (0) | 2025.04.14 |
---|---|
6주차 주간회고(4/5~4/11) (0) | 2025.04.11 |
NextJS - Routing (0) | 2025.04.09 |
Next.js 시작하기(Node.js 버전 업그레이드) (0) | 2025.04.08 |
5주차 주간회고(3/29~4/4) (0) | 2025.04.04 |