Dynamic Routes
0. 시작하기 전..
- 코딩앙마님의 강의를 참고하였습니다! (강의영상 바로가기)
- 사용된 API
1. Dynamic Routes 배우기 전
- 이젠 api를 통해서 상품을 불러오겠습니다.
- #1. api 호출을 위해서 VScode 터미널에 npm i axios를 입력하여, 설치해줍니다.
- #2. 이제 index.js에 다음과 같이 입력합니다.
import Axios from "axios";
import Head from "next/head";
import { useEffect, useState } from "react";
import ItemList from "@/src/component/ItemList";
import styles from "@/styles/Home.module.css";
import { Divider, Header } from "semantic-ui-react";
export default function Home() {
const [list, setList] = useState([]);
const API_URL =
"http://makeup-api.herokuapp.com/api/v1/products.json?brand=maybelline";
function getData() {
// 상품을 받아옴
Axios.get(API_URL).then((res) => {
console.log(res.data);
setList(res.data);
});
}
useEffect(() => {
getData();
}, []);
return (
<div>
<Head>
<title>NewBean</title>
</Head>
<Header as="h3" style={{ paddingTop: 40 }}>
베스트 상품
</Header>
<Divider />
<ItemList list={list.slice(0, 9)} />
<Header as="h3" style={{ paddingTop: 40 }}>
신상품
</Header>
<Divider />
<ItemList list={list.slice(9)} />
</div>
);
}
- #3. component 폴더에 ItemList.js 파일을 생성 후, 다음과 같이 입력합니다.
import { Grid } from "semantic-ui-react";
import styles from "./ItemList.module.css";
export default function ItemList({ list }) {
return (
<div>
{/* Grid는 시맨틱 UI 리액트에서 불러옴 */}
<Grid columns={3}>
<Grid.Row>
{list.map((item) => (
<Grid.Column>
<div className={styles.wrap}>
<img
src={item.image_link}
alt={item.name}
className={styles.img_item}
/>
<strong className={styles.tit_item}>{item.name}</strong>
<span className={styles.txt_info}>
{item.category} {item.product_type}
</span>
<strong className={styles.num_price}>${item.price}</strong>
</div>
</Grid.Column>
))}
</Grid.Row>
</Grid>
</div>
);
}
- #4. component 폴더에 ItemList.module.css 파일을 생성한 후, 다음과 같이 입력합니다.
.wrap {
padding-bottom: 20px;
text-align: center;
}
.img_item {
display: block;
margin: 0 auto;
}
.tit_item {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
width: 160px;
margin: 10px auto;
}
.txt_info {
display: block;
margin-bottom: 10px;
color: #999;
text-align: center;
}
.num_price {
font-size: 17px;
font-weight: bold;
color: #00bcd4;
}
- #5. 이제 브라우저에 들어가 localhost:3000을 입력해봅시다.
→ 그럼 다음과 같이 제대로 상품이 출력되는 것을 확인할 수 있습니다.
2. Dynamic Routes
- 이제, Dynamic Routes를 사용하여 상품 ID가 달라도 하나의 페이지로 관리하고, next/link를 이용해 새로고침 없이 페이지 이동을 해봅시다.
- #1. view 폴더에서 [id].js 파일을 생성한 후, 다음과 같이 입력해줍니다.
import { useRouter } from "next/router";
const Post = () => {
const router = useRouter();
const { id } = router.query;
return <p>Post: {id}</p>;
};
export default Post;
- #2. 그 다음 ItemList.js에 들어가 다음과 같이 입력하여, Link를 추가해줍니다.
→ 브라우저로 가서 상품을 클릭하면, Post: 숫자가 나오는 것을 확인할 수 있습니다.
→ 잊은 것이 있었는데, map안에 있는 Grid.Column 태그 안에 key를 추가해줍니다.
import { Grid } from "semantic-ui-react";
import Link from "next/link";
import styles from "./ItemList.module.css";
export default function ItemList({ list }) {
return (
<div>
{/* Grid는 시맨틱 UI 리액트에서 불러옴 */}
<Grid columns={3}>
<Grid.Row>
{list.map((item) => (
<Grid.Column key={item.id}>
<Link href={`/view/${item.id}`}>
<div className={styles.wrap}>
<img
src={item.image_link}
alt={item.name}
className={styles.img_item}
/>
<strong className={styles.tit_item}>{item.name}</strong>
<span className={styles.txt_info}>
{item.category} {item.product_type}
</span>
<strong className={styles.num_price}>${item.price}</strong>
</div>
</Link>
</Grid.Column>
))}
</Grid.Row>
</Grid>
</div>
);
}
- #3. 이제 상세페이지를 디자인해봅시다. [id].js에 들어가 다음과 같이 입력합니다.
import Axios from "axios";
import { useRouter } from "next/router";
import { useEffect, useState } from "react";
import Item from "../../src/component/Item";
const Post = () => {
const router = useRouter();
const { id } = router.query;
const [item, setItem] = useState({});
const API_URL = `http://makeup-api.herokuapp.com/api/v1/products/${id}.json`;
function getData() {
Axios.get(API_URL).then((res) => {
setItem(res.data);
});
}
useEffect(() => {
if (id && id > 0) {
getData();
}
}, [id]);
return <Item item={item} />;
};
export default Post;
- #4. component 폴더 안에 Item.js 파일을 생성한 후, 다음과 같이 입력해줍니다.
import { Button, Header } from "semantic-ui-react";
import styles from "./Item.module.css";
export default function Item({ item }) {
const {
name,
image_link,
price,
description,
updated_at,
category,
product_type,
product_link,
} = item;
return (
<>
<div className={styles.wrap}>
<div className={styles.img_item}>
<img src={image_link} alt={name} />
</div>
<div className={styles.info_item}>
<strong className={styles.tit_item}>{name}</strong>
<strong className={styles.num_price}>${price}</strong>
<span className={styles.txt_info}>
{category ? `${category}/` : ""}
{product_type}
</span>
<Button color="orange">구매하기</Button>
</div>
</div>
<Header as="h3">Description</Header>
<p style={{ paddingBottom: 20, fontSize: 18 }}>{description}</p>
</>
);
}
- #5. component 폴더 안에 Item.module.css 파일을 생성한 후, 다음과 같이 입력합니다.
.wrap {
display: flex;
padding: 40px 0;
border-bottom: 1px solid #ccc;
}
.img_item {
flex: 200px 0 0;
}
.img_item img {
display: block;
}
.info_item {
flex: 1 0 0;
}
.tit_item {
display: block;
font-size: 24px;
margin-top: 20px;
}
.num_price {
display: block;
font-size: 34px;
margin-top: 20px;
color: #00bcd4;
}
.txt_info {
display: block;
font-size: 24px;
margin: 20px 0 40px;
}
- #6. 이제 마지막으로 브라우저에 들어가서 확인해봅시다!
→ 상세페이지가 제대로 나타나는 것을 확인할 수 있습니다.
3. 정리하며
- 지금까지 dynamic routers에 대해 알아보았고, 메인 페이지와 상세 페이지를 작업해 보았습니다.
※ 참고 깃 주소 : https://github.com/NewBean0312/nextjs-study/commit/684f331eae156c4649ed1dc086a06ff55e0f939f
'Front-End Study > Next.js' 카테고리의 다른 글
에러 페이지와 환경 변수 (0) | 2023.12.13 |
---|---|
서버사이드 렌더링 (0) | 2023.12.12 |
페이지 레이아웃 생성 (0) | 2023.12.01 |
Next.js 설치 (0) | 2023.12.01 |
Next.js (0) | 2023.12.01 |