💡 React의 내장 함수들로만 구현한 데이터 fetching 예시.
export default function HomePage() { 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>{!isLoading ? JSON.stringify(movies) : "Loading..."}</div>; }
💡 NextJs로 구현한 데이터 fetching 예시.
export const metadata = { title: "Home", }; 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 HomePage() { // await를 쓰기 위해서는 그 부모 함수는 async 해야 한다. const movies = await getMovies(); return <div>{JSON.stringify(movies)}</div>; }
🗣️ 단 위와 같은 경우에도 단점이 존재하는데, 만일 유저가 페이지에 도착했음에도 서버에서 데이터를 fetch하는데 오랜 시간을 소모하게 된다면, 유저는 데이터 fetch가 끝날 때까지 아무런 화면도 보지 못하게 된다.
🗣️ 서버 사이드 렌더링시에 단점 :
NextJs에서는 백엔드에서 데이터들을 fetch해오기 때문에 해당 작업이 완료되기 전에는, 백엔드에서 랜더링이 이루어지지 않게 되므로 유저는 해당 페이지에서 아무것도 볼 수 없음.
💡 해당 문제에 대한 해결방법? loading.tsx
- app/(home)/ 디렉토리 안에, loading.tsx라는 파일을 새로 생성해 주면 된다.
// app/(home)/loading.tsx // 홈페이지 방문시에 보고싶은 로딩 화면이기 때문에 해당 page.tsx와 같은 디렉토리안에 파일을 만들어 줘야한다. export default function Loading() { return ( <div> <h1>Loading...</h1> </div> ); } // app/(home)/page.tsx export default async function HomePage() { // HomePage()가 async여야 하는 이유는 NextJs가 이 컴포넌트에서 await해야하기 때문이다. const movies = await getMovies(); return <div>{JSON.stringify(movies)}</div>; }
- NextJS는 서버 컴포넌트에서 데이터를 fetch하는 도중, 우선 layout, naviagaion등을 우선 UI로 그려주고나서 해당 loading.tsx안에 컴포넌트를 UI로 그려준다.
- 그러다 getMovies()의 마지막 결과값이 있는 컴포넌트가 브라우저에 전달되면 loading 컴포넌트가 유저가 원했던 HomePage()로 대체된다.
- 유저가 웹사이트에 도착하는 순간 NextJs는 즉시 사용자에게 로딩 상태를 주게되고 streaming을 사용해서 우리의 페이지를 작은 HTML로 나누어 준비된 HTML 부분을 브라우저에게 줄 수 있다.
- 스트리밍(streaming) : 프레임워크가 우리의 페이지를 작은 HTML부분으로 나누고 준비된 부분을 하나씩 보여주는 것을 의미