Web Devlopment/NextJs
#7. fetch
키모형
2025. 3. 28. 11:35
반응형
Client Side Fetch
"use client" 키워드 필요
- 클라이언트에서 페이지 render 후에 useEffect를 이용하여 fetch 를 요청해서 ui를 다시 render 함
- use client 를 선언해야 했기 때문에 meta data 도 해당 페이지에 적용 할 수 없음
- React App <=========> API <========> DB
"use client"
import { useEffect, useState } from "react"
// use client 선언으로 metatdata 사용불가가
// export const metadata = {
// title: "Home Page",
// }
export default function HomePage() {
const [isLoading, setIsLoading] = useState(true);
const [movies, setMovies] = useState([]);
const getMovies=async ()=>{
await fetch('https://nomad-movies.nomadcoders.workers.dev/movies')
.then((res) => res.json())
.then((data) => {
setMovies(data);
setIsLoading(false);
});
};
useEffect(()=>{
getMovies();
},[]);
return (
<div>
<h1>Hello, Next Movie!!</h1>
<div>
{isLoading ?"Loding Data..." : JSON.stringify(movies)}
</div>
</div>
)
}
Server Side Fetch
// use client 삭제
import { useEffect, useState } from "react"
// metadata 사용가능
export const metadata = {
title: "Home",
}
// server side async fetch 함수
// 서버에서 실행되기 때문에 api key 등 민감한 데이터를 다룰 수 있음
const URL = "https://nomad-movies.nomadcoders.workers.dev/movies";
async function getMovies(){
const response=await fetch(URL);
const json=await response.json();
return json;
}
// page function을 async 해주고
// 함수 내에서 fetch 결과를 받음
export default async function HomePage() {
const movies = await getMovies();
return (
<div>
<h1>Hello, Next Movie!!</h1>
<div>
{JSON.stringify(movies)}
</div>
</div>
)
}
- 서버쪽에서 fetch를 모두 완료 한 후에 클라이언트로 render해줌
- 또한, fetch 결과 cache 에 저장하여 다시 페이지로 이동을 하게 되면 cache 된 데이터를 보여줌
문제점
- 서버에서 모든 fetch 작업을 완료 할때 까지 클라이언트에 응답을 하지 않고 지연하게 됨
- fetch 작업중 로딩 표시 및 애러처리 작업 추가필요
loading.tsx
route groups (괄호그룹명) 폴더 내에 loading.tsx파일을 만들어 주면
해당 page.tsx가 backend 작업이 완료되기 전까지 loading.tsx 파일 내용을 보여주며
모든 작업이 완료 된 후에 page.tsx내용을 render 함
영화목록 수정
import Link from "next/link";
export const metadata = {
title: 'MOVIES',
}
// fetch 주소, async, await
const URL = "https://nomad-movies.nomadcoders.workers.dev/movies";
async function getMovies(){
const response=await fetch(URL);
const json=await response.json();
return json;
}
export default async function MovieHome() {
const movies = await getMovies();
return (
<div>
<h1>Hello, Next Movie!!</h1>
<div>
{(movies).map((movie)=> (
<li key={movie.id}>
<Link href={`/movies/${movie.id}`}>{movie.title}</Link>
</li>
))}
</div>
</div>
)
}
반응형