/components/movie-info.tsx

const API_URL = "<https://nomad-movies.nomadcoders.workers.dev/movies>"

async function getMovie(id: string) {
    await new Promise((response) => setTimeout(response, 3000))
    const response = await fetch(`${API_URL}/${id}`)
    return response.json()
}

export default async function MovieInfo({id}: {id: string}) {
    const movie = await getMovie(id)
    return <h6>{JSON.stringify(movie)}</h6>
}

/components/movie-videos.tsx

const API_URL = "<https://nomad-movies.nomadcoders.workers.dev/movies>"

async function getVideos(id: string) {
    await new Promise((response) => setTimeout(response, 5000))
    const response = await fetch(`${API_URL}/${id}/videos`)
    return response.json()
}

export default async function MovieVideos({id}: {id: string}) {
    const videos = await getVideos(id)
    return <h6>{JSON.stringify(videos)}</h6>
}

/movies/[id]/page.tsx

import MovieVideos from "../../../components/movie-videos";
import MovieInfo from "../../../components/movie-info";
import {Suspense} from "react";

export default async function MovieDetail({params: {id}}: {params: {id: string}}) {
    return <div>
        <Suspense fallback={<h1>Loading movie info</h1>}>
            <MovieInfo id={id} />
        </Suspense>
        <Suspense fallback={<h1>Loading movie video</h1>}>
            <MovieVideos id={id} />
        </Suspense>
    </div>
}

Next.js 영화 상세 페이지 구현 및 React Suspense를 활용한 데이터 페칭 최적화

1. 병렬 데이터 페칭의 장점

2. 데이터 페칭의 문제점

3. 페칭 함수 분리 및 컴포넌트화

4. React Suspense 도입