last-sales.js
import { useEffect, useState } from "react";
export default function LastSalesPage() {
const [sales, setSales] = useState();
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
setIsLoading(true);
fetch("https://nextjs-udemy-ad43d-default-rtdb.firebaseio.com/sales.json")
.then((res) => res.json())
.then((data) => {
console.log(data);
const transformedSales = [];
for (const key in data) {
transformedSales.push({
id: key,
username: data[key].username,
volume: data[key].volume,
});
}
setSales(transformedSales);
setIsLoading(false);
});
}, []);
if (isLoading) {
return <p>Loading...</p>;
}
if (!sales) {
return <p>No data yet</p>;
}
return (
<ul>
{sales.map((sale) => (
<li key={sale.id}>
{sale.username} - {sale.volume}
</li>
))}
</ul>
);
}
위 코드를 통해 Client Side Data Fetching에 대한 개념과 next.js의 기본 기능인 preRendering 에 대해 이해할 수 있다.
위 코드는 preRendering을 하기 위해 사용되는 getStaticProps, getServerSideProps 와 같은 함수를 사용하지 않고 client-side 에서 데이터를 가져오기 위해 useEffect에서 fetch를 사용하여 data fetching을 하는 코드이다.
결과적으로 http://localhost:3000/last-sales 로 들어가면 미리 firebase에 저장해놓은 데이터가 잘 가져와지는 것을 알 수 있다. 하지만 페이지 소스 보기
를 눌러보면
NO data yet 이라는 코드가 실행된 것을 확인할 수 있다.
이 코드는 sales state에 값이 없을 때의 return 값인데 정상적으로 값이 출력되었음에도 불구하고 왜 이 코드가 실행된것일까?
바로 next.js의 기본 기능인 preRendering 때문이다.
- getServerSideProps를 사용하지 않으면 next.js에서 자동으로 기본 페이지를 사전 렌더링 한다. (원래 next.js가 사전 렌더링을 하니까)
- 이 페이지에서 사용된 데이터는 next.js에서 getStaticProps와 같은 함수로 준비한 것이 아니기 때문에 next.js에서 페이지를 사전 렌더링 할때 useEffect를 거치지 않는다.
- 따라서 useEffect와는 상관 없이 이 컴포넌트에서 최초로 반환하는 결과로 사전 렌더링을 진행하고, 아무런 데이터가 없어서 No data yet이란 결과를 내뱉는다.