동적 라우팅을 빨리 써보고 싶어서 레이아웃 작업이 끝나기 전에 실행해봤어요!!
메인 상품 페이지에서 상품 클릭 시, 해당 상품의 상세정보를 보여줄 때 사용할 수 있습니다.
사용한 프레임워크 및 라이브러리
nextJS, react-hooks, scss, axios
nextJS는 페이지 전환에 최적화되어 있어 상황에 맞는 props를 쓸 수 있습니다. getInitialProps, serverSideProps, staticProps 등 필요에 따라 쓸 수 있는데 자세한 건 다음에 적용하고 공유하겠습니다!
폴더구조는 메인페이지와 상세페이지 2개가 있습니다. 메인페이지에는 해당 index.js파일과 자식컴포넌트인 ItemList파일이 있고, 상세페이지에는 /detail/[id] 파일이 한 개 있습니다. 상세페이지에서 보여주는 내용들은 공용컴포넌트를 자식으로 가져왔습니다.
pages의 api폴더안에 목데이터를 만들면 json파일로 가져올 수 있습니다.
/api/getRequestInfo.js
function requestDate() {
const date = new Date();
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
const hours = date.getHours();
const minutes = date.getMinutes();
return (
`${year}.` +
`${month < 10 ? 0 + "" + month : month}.` +
`${day < 10 ? 0 + "" + day : day} ` +
`${hours < 10 ? 0 + "" + hours : hours}:` +
`${minutes < 10 ? 0 + "" + minutes : minutes}`
);
}
const requestInfo = [
{
id: 1,
car_brand: "현카",
car_type: "부가티 센토디에치",
car_number: "01가1111",
phone_number: "+ 82 10 1234 1234",
location: "서울특별시 강남구",
date: requestDate(), // 2020.12.25 15:10,
description: "빠른 처리 부탁드립니다.",
},
{
id: 2,
car_brand: "동카",
car_type: "롤스로이스 스웹테일",
car_number: "02나2222",
phone_number: "+ 82 10 4321 4321",
location: "서울특별시 강남구",
date: requestDate(), // 2020.12.25 15:10,
description: "안녕하세요.",
},
{
id: 3,
car_brand: "류카",
car_type: "파가니 와이라 이몰라",
car_number: "03다3333",
phone_number: "+ 82 10 3333 5555",
location: "서울특별시 강남구",
date: requestDate(), // 2020.12.25 15:10,
description: "조심히 오세요.",
},
{
id: 4,
car_brand: "규카",
car_type: "부가티 디보",
car_number: "07라7777",
phone_number: "+ 82 10 7777 7777",
location: "서울특별시 강남구",
date: requestDate(), // 2020.12.25 15:10,
description: "조심히 오세요.",
},
{
id: 5,
car_brand: "영카",
car_type: "마이바흐 엑셀레로",
car_number: "05마5555",
phone_number: "+ 82 10 1049 4867",
location: "서울특별시 강남구",
date: requestDate(), // 2020.12.25 15:10,
description: "조심히 오세요.",
},
{
id: 6,
car_brand: "신카",
car_type: "부가티 라 부아튀르 누아르",
car_number: "06바6666",
phone_number: "+ 82 10 3333 5555",
location: "서울특별시 강남구",
date: requestDate(), // 2020.12.25 15:10,
description: "조심히 오세요.",
},
];
export default (req, res) => {
res.statusCode = 200;
res.json(requestInfo);
}
/index.js
import React, { Fragment, useEffect, useState } from "react";
import ItemList from "./ItemList";
import Axios from "axios";
function ReservationConfirmation() {
const [list, setList] = useState([]);
const API = "http://localhost:5700/api/getRequestInfo";
useEffect(() => {
Axios.get(API).then((res) => {
setList(res.data);
})
}, []
);
return(
<Fragment>
<ItemList list={list} />
</Fragment>)
}
export default ReservationConfirmation;
Axios의 메서드를 이용해서 데이터를 불러오고 자식 컴포넌트인 ItemList에 넘겨줍니다.
/ItemList.js
import React, { Fragment } from "react";
import Link from "next/link";
function ItemList({ list }) {
console.log(list);
return (
<Fragment>
<div>
{list?.map((info) => {
return (
<div style={{ margin: "50px", textAlign: "center" }} key={info.id}>
<Link href={`/user/main/reservation/detail/${info.id}`}>
<input type="button" value={"button" + info.id} alt="" />
</Link>
<div style={{ marginTop: "10px" }} />
<div>{info.car_brand}</div>
<div style={{ marginTop: "10px" }} />
<div>{info.car_type}</div>
</div>
);
})}
</div>
</Fragment>
);
}
export default ItemList;
여기까지는 데이터를 생성하고 가져오는 과정입니다. 그리고 버튼을 눌렀을 때 상세페이지로 가기 위해서 Link를 import해서 사용했습니다.
detail폴더를 생성하고 [id].js 파일을 생성해주면 id의 값에 따라서 경로가 생성됩니다.
ex) id===1인 버튼을 클릭했을 때, /detail/1 로 이동하게 됩니다.
/detail/[id].js
import React, { useEffect, useState } from "react";
import { useRouter } from "next/router";
import RequestDetailHeader from "../../../../../components/Header/RequestDetailHeader";
import RequestInfo from "../../../../../components/RequestDetail/RequestInfo";
import ProposalInfo from "../../../../../components/RequestDetail/ProposalInfo";
import Link from "next/link";
import axios from "axios";
import styles from "./ConfirmationDetail.scss";
import {
DISPATCH_CANCEL,
DISPATCH_COMPLETE,
} from "../../../../../constants/requestDetail/ProposalInfo";
const API = "http://localhost:5700/api/getRequestInfo";
const isReservation = true;
const ConfirmationDetail = () => {
const [list, setList] = useState([]);
useEffect(() => {
if (id && id > 0) {
axios.get(API).then((res) => {
setList(res.data);
});
}
}, [id]);
return (
<div className={styles.container}>
<RequestDetailHeader />
<div className={styles.menuTab}>
<Link href="/user/main/reservation/detail">
<a className={styles.active}>요청상세</a>
</Link>
<Link href="/user/main/reservation/detail/chat">
<a>채팅</a>
</Link>
</div>
<RequestInfo list={list} id={id} />
<ProposalInfo
isReservation={isReservation}
leftButtonValue={DISPATCH_CANCEL}
rightButtonValue={DISPATCH_COMPLETE}
/>
</div>
);
};
export default ConfirmationDetail;
상세페이지 index.js 파일 대신 [id].js 파일을 생성해주면 동적인 경로가 자동으로 지정됩니다.
정말 간단합니다. 로딩페이지의 시간단축 등의 성능개선을 위해서는 serverSideProps 또는 staticProps를 사용할 수 있습니다!
올ㅋ