소스 :
https://github.dev/mschwarzmueller/nextjs-course-code/tree/04-data-fetching
https://github.dev/mschwarzmueller/nextjs-course-code/tree/05-prj-data-fetching
https://nextjs-event1.netlify.app/

1.index.js
import fs from "fs";
import path from "path";
import Link from "next/link";
// HomePage 컴포넌트: props로 전달된 제품 목록을 렌더링
function HomePage(props) {
const { products } = props;
return (
<ul>
{products.map((product) => (
<li key={product.id}>
{/* 각 제품을 링크로 표시, 클릭 시 해당 제품의 상세 페이지로 이동 */}
<Link href={`/products/${product.id}`} >{product.title}</Link>
</li>
))}
</ul>
);
}
// getStaticProps 함수: 정적 페이지 생성을 위한 데이터 페칭
export async function getStaticProps(context) {
// 파일 경로 설정: 현재 작업 디렉토리에서 "data/dummy-backend.json" 파일을 가리킴
const filePath = path.join(process.cwd(), "data", "dummy-backend.json");
// 파일을 읽어 JSON 데이터를 문자열로 가져옴
const jsonData = fs.readFileSync(filePath, "utf8");
// JSON 문자열을 JavaScript 객체로 파싱
const data = JSON.parse(jsonData);
// 데이터가 없는 경우 '/no-data'로 리디렉션
if(!data){
return{
redirect:{
destination: '/no-data'
}
}
}
// 데이터에 제품이 없는 경우 404 페이지를 반환
if(data.products.length === 0) {
return { notFound: true };
}
// 데이터가 유효한 경우, props로 제품 목록을 전달
return {
props: {
products: data.products,
},
// 페이지를 10초마다 재생성하여 최신 데이터를 반영
revalidate: 10,
};
}
export default HomePage;
주석 요약
- HomePage 컴포넌트: props로 전달된 products 목록을 받아와 각 제품을 링크로 렌더링합니다. 클릭 시 제품의 상세 페이지로 이동합니다.
- getStaticProps 함수: Next.js의 정적 사이트 생성(SSG)을 위해 사용됩니다.
- 파일 경로 설정: dummy-backend.json 파일의 경로를 설정합니다.
- 파일 읽기: 해당 파일을 읽어 JSON 데이터를 문자열로 가져옵니다.
- JSON 파싱: 문자열을 JavaScript 객체로 파싱합니다.
- 데이터 검증 및 리디렉션/404 처리: 데이터가 없거나 제품이 없는 경우 적절하게 처리합니다.
- 유효한 데이터 반환: 유효한 데이터가 있는 경우, 이를 props로 전달하고 페이지를 10초마다 재생성하도록 설정합니다.
2.[pid].js
import React, { Fragment } from "react";
import fs from "fs";
import path from "path";
// ProductDetailPage 컴포넌트: props로 전달된 제품의 상세 정보를 렌더링
const ProductDetailPage = (props) => {
const { loadedProduct } = props;
// 로딩 상태 처리: 제품 정보가 없을 경우 로딩 메시지 표시
if (!loadedProduct) {
return <h1>Loading...</h1>;
}
// 제품 정보가 있을 경우 제목과 설명을 렌더링
return (
<Fragment>
<h1>{loadedProduct.title}</h1>
<p>{loadedProduct.description}</p>
</Fragment>
);
};
// 데이터 페칭 함수: 로컬 파일에서 제품 데이터를 읽어와 파싱
async function getData() {
const filePath = path.join(process.cwd(), "data", "dummy-backend.json");
const jsonData = fs.readFileSync(filePath, "utf8");
const data = JSON.parse(jsonData);
return data;
}
// getStaticProps 함수: 제품 상세 정보를 정적 페이지로 생성하기 위한 데이터 페칭
export async function getStaticProps(context) {
const { params } = context; // URL 매개변수에서 제품 ID 추출
const productId = params.pid;
const data = await getData(); // 데이터 페칭
// 제품 ID에 해당하는 제품 찾기
const product = data.products.find((product) => product.id === productId);
// 제품이 없을 경우 404 페이지 반환
if (!product) {
return { notFound: true };
}
// 제품이 있을 경우 제품 정보를 props로 전달
return {
props: {
loadedProduct: product,
},
};
}
// getStaticPaths 함수: 정적 경로를 생성하기 위한 모든 제품 ID를 지정
export async function getStaticPaths() {
const data = await getData(); // 데이터 페칭
const ids = data.products.map((product) => product.id); // 모든 제품 ID 추출
// 제품 ID를 이용하여 경로 생성
const pathsWithParams = ids.map((id) => ({ params: { pid: id } }));
return {
paths: pathsWithParams, // 생성할 경로 목록
fallback: false, // fallback 설정 (해당 경로가 없으면 404 페이지 반환)
};
}
export default ProductDetailPage;
주석 요약
- ProductDetailPage 컴포넌트: props로 전달된 loadedProduct를 사용하여 제품의 제목과 설명을 렌더링합니다. 제품 정보가 없을 경우 로딩 메시지를 표시합니다.
- getData 함수: 로컬 파일 시스템에서 제품 데이터를 읽어와 JSON 객체로 파싱합니다.
- getStaticProps 함수: Next.js의 정적 사이트 생성(SSG)을 위해 사용됩니다. params에서 제품 ID를 추출하고, 해당 ID의 제품 정보를 찾아 props로 전달합니다. 제품이 없을 경우 404 페이지를 반환합니다.
- getStaticPaths 함수: Next.js의 동적 경로를 위한 함수입니다. 모든 제품 ID를 사용하여 정적 경로를 생성합니다. fallback이 false로 설정되어 있어, 경로가 존재하지 않을 경우 404 페이지를 반환합니다.
3.[uid].js
// UserIdPage 컴포넌트: props로 전달된 사용자 ID를 렌더링
function UserIdPage(props) {
return <h1>{props.id}</h1>;
}
export default UserIdPage;
// getServerSideProps 함수: 서버 사이드에서 동적으로 데이터를 가져오기 위해 사용
export async function getServerSideProps(context) {
const { params, req, res } = context; // 요청 컨텍스트에서 매개변수, 요청, 응답 객체 추출
const userId = params.uid; // URL 매개변수에서 사용자 ID 추출
// props로 전달할 데이터 반환
return {
props: {
id: "userid-" + userId, // 사용자 ID를 "userid-" 접두어와 함께 반환
},
};
}
주석 요약
- UserIdPage 컴포넌트: props로 전달된 id를 사용하여 사용자 ID를 렌더링합니다.
- getServerSideProps 함수: Next.js의 서버 사이드 렌더링(SSR)을 위해 사용됩니다. 요청 컨텍스트에서 URL 매개변수, 요청 객체, 응답 객체를 추출합니다.
- params: URL 매개변수를 포함하며, 여기서 사용자 ID (uid)를 추출합니다.
- req 및 res: 요청(Request) 및 응답(Response) 객체로, 필요시 추가적인 처리를 할 수 있습니다.
- 반환값: props 객체를 반환하여 UserIdPage 컴포넌트에 사용자 ID를 전달합니다. userid- 접두어를 붙여서 반환합니다.
이 코드는 서버 사이드에서 사용자 ID를 동적으로 가져와 페이지를 렌더링하는 간단한 예제입니다.
4.client-photos.js
import { useEffect, useState } from "react";
import useSWR from "swr";
// Fetcher 함수 정의: 주어진 URL에서 데이터를 가져와 JSON으로 파싱
const fetcher = (...args) => fetch(...args).then(res => res.json())
// LastSalesPage 컴포넌트: 판매 데이터를 렌더링
function LastSalesPage() {
const [salesData, setSalesData] = useState([]); // 상태 변수로 판매 데이터 초기화
// useSWR 훅 사용: 지정된 URL에서 데이터를 가져옴
const { data, error, isValidating } = useSWR("https://jsonplaceholder.typicode.com/photos", fetcher);
// useEffect 훅 사용: 데이터가 변경될 때마다 판매 데이터를 설정
useEffect(() => {
if (data) {
console.log("==================>", data);
setSalesData(data);
}
}, [data]);
// 에러 발생 시 에러 메시지 렌더링
if (error) {
return <h1>Error....</h1>;
}
// 데이터가 유효화되고 있을 때 로딩 메시지 렌더링
if (isValidating) {
return <h1>Loading....</h1>;
}
// 판매 데이터를 렌더링
return (
<div>
<h1>Sales Data</h1>
<ul>
{salesData && salesData.map((sale) => (
<li key={sale.id}>
<img src={sale.thumbnailUrl} alt={sale.title} />
{sale.title}
</li>
))}
</ul>
</div>
);
}
export default LastSalesPage;
주석 요약
- Fetcher 함수: fetcher 함수는 주어진 URL에서 데이터를 가져와 JSON으로 파싱합니다.
- LastSalesPage 컴포넌트: 판매 데이터를 렌더링합니다.
- 상태 변수: salesData 상태 변수로 판매 데이터를 관리합니다.
- useSWR 훅: 지정된 URL에서 데이터를 가져오고, data, error, isValidating 값을 반환합니다.
- useEffect 훅: data가 변경될 때마다 salesData를 설정합니다.
- 에러 처리: 에러가 발생하면 에러 메시지를 렌더링합니다.
- 로딩 상태: 데이터가 유효화되고 있을 때 로딩 메시지를 렌더링합니다.
- 데이터 렌더링: salesData를 렌더링하고 각 항목에 이미지와 제목을 표시합니다
5.sever-photos.js
import { useEffect, useState } from "react";
import useSWR from 'swr';
// 데이터 가져오는 fetcher 함수 정의
const fetcher = (...args) => fetch(...args).then(res => res.json())
// LastSalesPage 컴포넌트 정의
function LastSalesPage({ initialData }) {
// 상태 변수 정의: initialData를 초기 값으로 설정
const [salesData, setSalesData] = useState(initialData);
// useSWR 훅 사용: 데이터를 가져오고 상태 관리
const { data, error, isValidating } = useSWR("https://jsonplaceholder.typicode.com/photos", fetcher, {
initialData, // 초기 데이터 설정
});
// useEffect 훅 사용: 데이터가 업데이트될 때마다 상태 업데이트
useEffect(() => {
if (data) {
setSalesData(data); // 데이터가 있으면 salesData 상태 업데이트
}
}, [data]); // data가 변경될 때 useEffect 실행
// 에러 발생 시 에러 메시지 출력
if (error) {
return <h1>Error....</h1>;
}
// 데이터 유효화 중일 때 로딩 메시지 출력
if (isValidating) {
return <h1>Loading....</h1>;
}
// 정상적으로 데이터가 로드된 경우 판매 데이터 렌더링
return (
<div>
<h1>Sales Data</h1>
<ul>
{salesData &&
salesData.map((sale) => (
<li key={sale.id}>
<img src={sale.thumbnailUrl} alt={sale.title} />
{sale.title}
</li>
))}
</ul>
</div>
);
}
// getStaticProps 함수: 정적 페이지 생성을 위해 데이터를 사전에 가져옴
export async function getStaticProps() {
const data = await fetcher("https://jsonplaceholder.typicode.com/photos"); // 데이터 가져오기
return {
props: {
initialData: data, // 초기 데이터를 props로 전달
},
};
}
export default LastSalesPage; // 컴포넌트 export
주석 요약
- fetcher 함수: 주어진 URL에서 데이터를 가져와 JSON으로 파싱하는 함수입니다.
- LastSalesPage 컴포넌트: 판매 데이터를 렌더링하는 함수형 컴포넌트입니다.
- 상태 관리: useState 훅을 사용하여 salesData 상태를 관리합니다.
- 데이터 가져오기: useSWR 훅을 사용하여 주어진 URL에서 데이터를 가져옵니다. initialData로 초기 데이터를 설정합니다.
- 데이터 업데이트: useEffect 훅을 사용하여 data가 업데이트될 때마다 salesData 상태를 업데이트합니다.
- 에러 처리: error가 발생하면 에러 메시지를 출력합니다.
- 로딩 상태: 데이터를 가져오는 중일 때 isValidating 값에 따라 로딩 메시지를 출력합니다.
- 데이터 렌더링: 정상적으로 데이터를 로드하면 판매 데이터를 화면에 렌더링합니다.
- getStaticProps 함수: Next.js에서 정적 페이지 생성을 위해 데이터를 사전에 가져오는 함수입니다. fetcher를 사용하여 데이터를 가져온 후, 초기 데이터를 props로 전달합니다.
이 코드는 Next.js와 swr 라이브러리를 사용하여 데이터를 비동기적으로 가져오고, 정적 페이지 생성에 필요한 초기 데이터를 사전에 준비하는 방법을 보여줍니다.














댓글 ( 0)
댓글 남기기