참치코더의 꿈 메모장

Next.js / Suspense 사용법(각 컴포넌트 캐시 할당 및 병렬 출력), Error 페이지 만드는 방법 정리 (코드 위주) 본문

Next.js

Next.js / Suspense 사용법(각 컴포넌트 캐시 할당 및 병렬 출력), Error 페이지 만드는 방법 정리 (코드 위주)

참치깡 2025. 10. 6. 23:06
728x90

 

제미나이가 생성한 Next.js 이미지

 

 

 -  Promise.all을 사용하면 모든 API데이터를 다운로드 받을때까지 브라우저가 대기해 모든 데이터를 다운로드 후 창이 뜨는 

   문제가 발생한다.

 

- 이를 해결하기 위한 방법으로 React Suspense를 사용한다!!!

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
 
// component/movie-videos.tsx
 
import {API_URL} from "../app/(home)/page"
 
async function getVideos(id: string) {
    console.log(`Fetching videos: ${Date.now()}`); // 영화 비디오 api 데이터 fetch
    const response = await fetch(`${API_URL}/${id}/videos`);
    return await response.json();
}
 
export default async function MovieVideos({id}: {id: string}){
    
    const videos = await getVideos(id);
    return <h6>{JSON.stringify(videos)}</h6>
    
}
 
 // component/movie-info.tsx
 
import {API_URL} from "../app/(home)/page"
 
async function getMovie(id: string) {
    console.log(`Fetching movies: ${Date.now()}`);
    const response = await fetch(`${API_URL}/${id}`); //영화 api 데이터 fetch
    return await response.json();
}
export default async function MovieInfo({id}: {id: string}){
    
    const movie = await getMovie(id);
    return <h6>{JSON.stringify(movie)}</h6>
    
}
 
// 위에 여러 컴포넌트를 따로따로 로딩되는대로 띄울수 있도록 해주는 기능은 Suspense를 사용하면 된다.
// Suspense를 사용한다면 각각의 api가 로딩이 되는대로 해당하는 페이지 부분에 띄울 수 있다.
// 또한 fallback state를 사용한다면 해당 부분의 데이터가 뜨기 전에 표시할 내용을 생성할 수도 있다.
 
// 해당 폴더에 loading.tsx 페이지를 만드는 점과 다른점은 loading.tsx는 전체 페이지가 로딩중일때 해당 페이지를 사용자에게 
// 보여주는것 fallback state는 해당 컴포넌트 영역이 뜨기 전까지의 로딩창을 보여주는 점이 다르다. (영역의 차이점)
 
// 참고로 Suspense 기능은 Next.js의 기능이 아니라 React의 기능이다.
 
 
 // (movies)/movies/[id]/page.tsx
 
import { Suspense } from "react";
import MovieInfo from "../../../../components/movie-info";
import MovieVideos from "../../../../components/movie-videos";
 
export default async function MovieDetail({
    params,
}: {
    params: Promise<{id: string}>
}){
    const {id} = await params;
    return(
        <div>
            <Suspense fallback={<h1>Loading movie info</h1>}>
                <MovieInfo id={id} />
            </Suspense>
            <Suspense fallback={<h1>Loading movie videos</h1>}>
                <MovieVideos id={id} />
            </Suspense>
        </div>
    );
}
 
//////////////////////////////////////////////////
 
// 오류 페이지 만드는 방법 //
 
//////////////////////////////////////////////////
 
 
import { API_URL } from "../app/(home)/page";
 
async function getVideos(id :string){
    console.log(`Fetching videos: ${Date.now()}`);
    await new Promise((resolve) => {setTimeout(resolve, 3000)});
 
    throw new Error('something broke...'); // 강제오류 발생
 
    //const response = await fetch(`${API_URL}/${id}/videos`);
    //return await response.json();
}
 
export default async function MovieVideos({id}: {id: string}){
    
    const videos = await getVideos(id);
    return <h6>{JSON.stringify(videos)}</h6>
}
 
// 이렇게 API 실행 도중에 오류가 발생하게 된다면, 개발자 페이지로 오류가 난 구문을 표시해주게 된다.
// 실 사용 서버에서 이런 오류가 난다면 사용자들은 내부 코드를 볼 뿐더러, 가독성이 좋지가 않다.
// 이를 위해 Next.js에서는 오류가 났을때 보여줄 페이지를 만들수 있는 기능을 제공한다.
 
// 그냥 오류를 띄우고 싶은 페이지의 폴더 경로에 error.tsx 페이지를 생성하면 오류가 발생했을때 Next.js가
// 해당 에러페이지를 자동으로 띄워준다. (에러 페이지는 'use client' 사용)
 
 
 // (movies)/movies/[id]/error.tsx
 
'use client';
 
export default function ErrorPage(){
    return <h1>error page........... 404........ </h1>
 
 
 
 
 
 
cs
728x90
Comments