client component์์ ๊ธฐ์กด์ API์ ์ํตํ๋ ๋ฐฉ์
- useEffect
- useState -> metadata ์ฌ์ฉ ๋ถ๊ฐ
- ๋ก๋ฉ state ๊ตฌํ
'use client';
import { useEffect, useState } from 'react';
/* useState์ ์ฌ์ฉ์ผ๋ก ์ธํด, ์ฌ์ฉ ๋ถ๊ฐ๋ฅ
export const metadata = {
title: 'Home',
};
*/
export default function Page() {
const [isLoading, setIsLoading] = useState(true);
const [movies, setMovies] = useState([]); //useState -> interactive component๋ฅผ ์ฌ์ฉํ๊ฒ ๋ค. -> "use client" ์์ฑ ํ์
const getMovies = async () => {
const response = await fetch('URL');
const json = await response.json();
setMovies(json);
setIsLoading(false);
};
useEffect(() => {
getMovies();
}, []);
return <div>{isLoading ? 'Loading...' : JSON.stringify(movies)}</div>;
}
(Next.js ํ๋ ์์ํฌ ์ฌ์ฉ) server component์์ fetch
- useEffect, useState ์ฌ์ฉ ์์ด ๋์ผํ ๊ธฐ๋ฅ ๊ตฌํ ๊ฐ๋ฅ
- Next.js ๋ ์๋์ผ๋ก fetch๋ url์ ์บ์ฑํ๋ค -> ์๋ก๊ณ ์นจ ์, ๋ค์ fetch X
- Loading ์ํ๊ฐ ์๋ค? -> no, ์ฒ์ fetch ํ ๋ API๊ฐ ๋๋ฆฌ๋ค๋ฉด ๋ฐ์ ๊ฐ๋ฅ
- ํ์ง๋ง ๋ฐฑ์๋์์ fetchํ๊ณ ์๊ธฐ ๋๋ฌธ์, ๋ก๋ฉ ์ํ๋์ web page ์์ฒด๋ฅผ ๋ณด์ฌ์ฃผ์ง ์์
// /app/page.tsx
export const metadata = {
title: 'Home',
};
const URL = 'URL';
async function getMovies() {
// const response = await fetch(URL);
// const json = await response.json();
// return json;
//์ ์ฝ๋๋ฅผ ์ค์ธ ๊ฒ
return fetch(URL).then(response => response.json());
}
//์ด๋ค ์ผ์ด ๋ฐ์ํ๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ค๊ณ ํ ๋, await ์ฌ์ฉ -> await๋ async ํจ์ ์์์๋ง ์ฌ์ฉ ๊ฐ๋ฅ
export default async function HomePage() {
const movies = await getMovies();
return <div>{JSON.stringify(movies)}</div>;
}
- (page.tsx ํ์ผ๊ณผ ๊ฐ์ ์์น์) loading.tsx ํ์ผ์ ๋ง๋ค์ด์ฃผ๋ฉด, ํ๋ ์์ํฌ๋ ํด๋น ํ์ผ์ ์๋์ผ๋ก loading page component๋ก ๋ฐ๊พผ๋ค.
- ๋ฐฑ์๋ ์๋ฒ์์ ์๋ต ๋๊ธฐ ์, ์ ์ ๋ ์นUI๋ฅผ ๊ธฐ๋ค๋ฆฌ๋๊ฒ ์๋๊ณ loading component ๋ฅผ ๋ฐ๋ก ๋ณด๊ฒ๋จ.
- ๋ฐฑ์๋ ์๋ฒ ์๋ต ์๋ฃ ์, ํ๋ก ํธ์๋ ํ๋ ์์ํฌ๋ loading component ๋์ ๊ธฐ์กด page ๋ ๋๋ง
// /app/loading.tsx
export default function Loading(){
return <h2>Loading...</h2>
}