fetch, streaming, suspense, boundary 등을 배울것이다.
쉽고 멋지다고 한다.
NextJS 의 fetching을 위해 영화 상세보기 API를 이용하자.
[출처-노마드코더] : https://nomad-movies.nomadcoders.workers.dev/
/: This page
/movies: List popular movies
/movies/:id: Get movie by :id
/movies/:id/credits: Get credits for a movie by :id
/movies/:id/videos: Get videos for a movie by :id
/movies/:id/providers: Get providers for a movie by :id
/movies/:id/similar: Get similar movies for a movie by :id
url 종류는 위와 같다.
"use client";
// 과거에 리액트에서 하던 방식의 클라이언트 fetch는 아래와 같다.
import { useEffect, useState } from "react";
export default function HOME() {
const [isLoading, setIsLoading] = useState(true);
const [movies, setMovies] = useState([]);
const getMovies = async () => {
const response = await fetch(
"https://nomad-movies.nomadcoders.workers.dev/movies"
);
const json = await response.json();
setMovies(json);
setIsLoading(false);
};
useEffect(() => {
getMovies();
}, []);
return (
<div>
<h1>HOME</h1>
<p>{isLoading ? "...isLoading" : JSON.stringify(movies)}</p>
</div>
);
}
기존방식: React API <===> API <===> DB
이렇게 하면 네트워크 탭을 열면 누구나 api를 보고 쿼리를 통해 정보를 찾을 수 있어서 보안적으로 안전하지 않은 경우가 있다.
모든것을 client 에서 fetching을 하면 API에서 보안을 위해 DB요청하는 중간의 API이 필요했다. 하지만 NextJS 는 중간의 백엔드 API 없이 DB에서 바로 데이터를 가져올 수 있다.
또한 React앱에서는 로딩 상태를 항상 신경써서 직접 만들어야 하고, useState를 사용해서 데이터를 관리해야 한다.
하지만 server component 에서 fetching을 하면, useEffect와 useState, Loding을 사용하지 않아도 된다.
그리고 프론트엔드 개발자는 백엔드가 만든 API가 필요하지 않게 된다.
//next.js
// 브라우저에서는 아무것도 fetch하지 않는다.
export const metadata = {
title: "Home",
};
const MoviesURL = "https://nomad-movies.nomadcoders.workers.dev/movies";
async function getMovies() {
const response = await fetch(MoviesURL);
const json = await response.json();
return json;
}
// 한번만 서버에서 fetch 하면 캐시된다. server component 에서 Next JS 가 fetch한 것을 기억하고 있기 때문이다.
// 새로고침해도 이미 응답이 캐시되었기 때문에 로딩이 필요 없다
// 하지만 만약 서버 끄고 재 실행된다면 로딩이 필요하다. 즉 첫번째 fetch한 데이터가 존재하면 API에 요청하지 않고 캐싱된 데이터를 보여준다.
export default async function HomePage() {
const movies = await getMovies();
return <div>{JSON.stringify(movies)}</div>;
}
최신 데이터가 필요할때는 캐싱이나 revalidation을 해야한다.
백엔드의 응답까지 첫 초기 렌더링이 UI 가 표기되지 않는 멈춤상태로 있는 설정이 싫고 최소한의 정적 UI를(네비게이션) 보고있게 하고 싶다면 loading파일을 하나 만들어서 해결할 수 있다. loading.tsx 파일을 만들어주자
export default function Loading() {
return <h2>Loading...</h2>;
}
loading 파일만 제공 해줘도 된다.
이것은 백엔드가 페이지를 streaming 하기 때문에 가능하다.
백엔드에서 fetch함수가 완료되면 결과값을 브라우저에 보낸다. 그래서 layout과 navigation을 먼저 보내고 loading이 끝난 결과값을 보여주면 된다.
네트워크 탭을 열면 로딩중이라면 localhost가 로딩중임을 확인 할 수 있다. 이때 NextJS는 브라우저의 일부를 보여주며 기다려 달라고 하고, loading컴포넌트가 교체되는 것이다. 그리고 HomePage가 async인 이유는 준비된 Html 부분을 브라우저에 전달하기 위함이다.