의외로 당황했던 부분은, 이 메서드를 쓰는 방법은 알겠는데 그래서 어디에서 선언해주어야 하는 것인지, 이 메서드에서 호출한 데이터를 어디에서 어떻게 props로 전달받아 사용하는 것인지 모르겠다는 것이었다. 다른 코드들을 구글링해서 찾아봐도 이 부분에 대해서는 알기 어려웠다. 아마 다른 사람들에게는 너무나 당연한 부분인데, 나 혼자 몰랐나 보다.
그래서! 내가 정리해야겠다!
나 같은 사람이 또 있다면 참고할 수 있도록!
컴포넌트 선언문 밖에다가 적어주면 된다. 당연한 말이지만 컴포넌트 export문 위,아래 상관 없이 컴포넌트 밖에 적어주면 된다.
return (
// 생략
);
}
export const getStaticProps: GetStaticProps = async () => {
// 생략
};
export default Contacts;
// 여기에도 작성해도 된다.
그리고 이 데이터를 사용할 컴포넌트에서 props를 그대로 사용하면 되는데, 구조분해 할당을 원한다면 다음과 같이 일반적으로 props를 전달받을 때와 동일하게 작성해주면 된다.
function Contacts({ qaTypes, qas }) {
그럼, 어떻게 사용했는지 알아보자.
이번 프로젝트에서 맡은 페이지는 고객센터 페이지와 상품 목록 페이지 2개였다.
페이지 별 렌더링 방식을 결정한 내용과, 전체 프로젝트에 대한 내용은 아래 회고 포스팅에 담았다.
👉 포스팅 보러가기
getStaticProps는 빌드 시점에 api를 호출하고 데이터를 응답 받아서 HTML 을 완성하는 정적생성을 위한 메서드이다.
GetStaticProps 타입을 지정해준다음 원하는 데이터를 호출하고, 응답값을 return 문 내에서 props에 지정해준다.
export const getStaticProps: GetStaticProps = async () => {
const qaType = {
buy: 1,
sell: 2,
};
const qaTypesRes = await axios.get(FAQ_TYPE);
const buyQaRes = await axios.get(FAQ_CONTENT(qaType.buy));
const sellQaRes = await axios.get(FAQ_CONTENT(qaType.sell));
return {
props: {
qaTypes: qaTypesRes.data.qaTypes,
qas: {
1: buyQaRes.data.qas,
2: sellQaRes.data.qas,
},
},
};
};
export default Contacts;
사실 메서드 이름만 다를 뿐 사용법은 똑같다.
getServerSideProps는 context라는 인자를 받는다.
export async function getServerSideProps(context) {
return {
props: {
//
}
}
}
context 안에는 다음과 같은 파라미터들이 포함되어 있다.
getServerSideProps 메서드는 페이지가 호출될 때마다 요청된다.따라서 request 파라미터도 포함되어 있다.
이번 프로젝트에서는 params와 query만 사용해보았다.
나머지 파라미터에 대해서는 아직 잘 모르겠지만, 기회가 될 때 사용해보며 공부해봐야겠다.
### ❗️ params, query로 router.query 대체하기
>프로젝트 진행에서 문제가 되는 부분이 있었다.
홈 페이지 > 브랜드 페이지 > 목록 페이지 순으로 이동하면서 보여주어야 했다.
1. 홈 페이지에서 카테고리1, 즉 카페나 편의점을 선택하면
브랜드 페이지에서 해당 카테고리1에 해당하는 브랜드들을 보여준다.
- 예:카페클릭 -> 스타벅스, 투썸 플레이스 등 카페 브랜드 표시
2. 이 브랜드를 클릭하면 해당 브랜드의 기프티콘 상품을 보여준다.
- 예: 스타벅스 클릭 -> 스타벅스 기프티콘 목록 표시
![](https://velog.velcdn.com/images%2Fgygy%2Fpost%2Ff4e5f7bb-d396-49c4-aaf2-8fc245b1924d%2Fezgif.com-gif-maker%20(18).gif)
데이터 모델은 conCategory1과 conCategory2 두개의 뎁스로 이루어져있었다.
목록 페이지에서 상품목록들을 보여주려면 이 2개의 id가 필요했다.
카페 -> 스타벅스의 상품들을 모여주려면
conCategory1인 카페의 id 67, conCategory2인 스타벅스의 id 63이 필요했다.
{
"conCategory1": {
"id": 67,
"name": "카페",
"discountRate": 50,
"imageUrl": "imgsrc.jpg",
"conCategory2s": [
{
"id": 63,
"name": "스타벅스",
"conCategory1Id": 67,
"imageUrl": "imgsrc.jpg",
"conItems": [
{
"id": 137,
"name": "카페아메리카노 T",
"originalPrice": 4500,
"minSellingPrice": 3830,
"count": 15719,
"imageUrl": "imgsrc.jpg"
},
{
"id": 3308,
"name": "무료음료쿠폰 Tall (추가결제시 사이즈업가능)",
"originalPrice": 6300,
"minSellingPrice": 4850,
"count": 2609,
"imageUrl": "imgsrc.jpg"
}
]
브랜드 페이지에서 해당 conCategory1의 id와 클릭한 conCategory2의 id는 쿼리스트링으로 Link 태그를 통해 넘겨주었고, 이것을 Next.js에서 제공하는 useRouter()메서드를 사용해 router.query를 받아오려고 했다.
> 문제는!
query 값이 받아와지지 않아 데이터 호출을 할 수 없었던 것이다.
router.query의 값은 페이지가 2번 렌더링되면서 undefined였다가 이후에 맞는 값이 할당된다.
그런데 그전에 데이터를 받아와 화면을 그려야 하고,, 이 id값을 파라미터로 사용해야 했기 때문에 데이터 호출에서 에러가 발생했다.
> 이 문제, 어떻게 해결했을까?
바로 getServerSideProps의 params,와 query라는 props를 사용하는 것!
- params: 현재 url의 파라미터를 받아올 수 있다.
- query: 현재 url의 쿼리파라미터를 받아올 수 있다.
```tsx
export const getServerSideProps: GetServerSideProps = async ({
params,
query,
}) => {
const res = await axios.get(
`https://api2.ncnc.app/con-category1s/${params.id}/nested`,
);
return {
props: {
query: query.conCate2,
data: res.data,
},
};
};
예를 들어,
url/brands/67?conCate2=63
이렇게 conCategory1과 conCategory2의 id값을 쿼리스트링으로 넣었다고 하자.
그러면 params에는 {id: 67}
query에는 {conCate2: 63}
의 데이터가 담긴다.
(참고로 이 목록페이지는 brands/[id].tsx
로 동적 라우팅을 했기 때문에 params에 id라는 key로 값이 담긴다.)
그러면 해당하는 params로 conCategory1의 id값을 넣어 데이터를 호출해 사용할 수 있다.
query로 전달되는 conCategory2는 이 conCategory1에 해당하는 데이터 중 특정 브랜드의 상품만 필터링하기 위해 필요했기 때문에, 페이지내에서 사용할 수 있도록 함께 props로 전달해주었다.