상수 데이터 : 변하지 않는 정적인 데이터
예 ) 페이지를 구성할 때 UI 구성에 필요하지만 동적으로 변하지 않아 백엔드 API를 통해 가져올 필요가 없는 데이터.
Github 페이지 상단의 메뉴와 드랍다운
깃헙 footer
반복되는 UI를 하드코딩으로 일일이 만들면 가독성이 좋지 않고 유지보수도 어렵게 된다.
하지만 상수 데이터를 활용하면 arr.map() 메서드와 조합하여 반복 UI를 간결하게 표현 가능하다.
수정을 위해 return하는 JSX부분만, 내용은 상수 데이터 부분만 수정하면 되기 때문에 유지보수가 용이해진다.
const Footer = () => {
return (
<footer>
{/* 생략 */}
<ul>
<li>
<a href="https://github.com/terms">Terms</a>
</li>
<li>
<a href="https://github.com/privacy">Privacy</a>
</li>
...
<li>
<a href="https://github.com/about">About</a>
</li>
</ul>
</footer>
);
};
상수 데이터 활용 X 단점
1. 동일한 태그를 개수만큼 붙여넣기하는 비효율성
2. 특정 요소 수정 시 어려움
상수 데이터 이름 : UPPER_SNAKE_CASE(convention)
상수 데이터 형태 : 배열(요소는 객체, 스트링..등등)
const FOOTER_INFO_LIST = [
{ id: 1, link: 'https://github.com/terms', text: 'Terms' },
{ id: 2, link: 'https://github.com/privacy', text: 'Privacy' },
...
{ id: 11, link: 'https://github.com/about', text: 'About' },
];
🧨 주의: map메서드 활용 시 key 값 설정.
const Footer = () => {
return (
<footer>
{/* 생략 */}
<ul>
{FOOTER_INFO_LIST.map((info) => (
<li key={info.id}>
<a href={info.link}>{info.text}</a>
</li>
))}
</ul>
</footer>
);
};
-------컴포넌트 만들어서도 가능
<ul>
{FOOTER_INFO_LIST.map((info) => (
<FooterInfo key={info.id} link={info.link} text={info.text} />
))}
</ul>
상수 데이터가 해당 컴포에서만 사용되고 가독성을 해치지 않을 때는~
예) 위에서 map메서드 사용한 FOOTER_INFO_LIST 데이터 같은 경우는 변하지 않는 상수 데이터이기에 컴포넌트 외부에 작성했음.
상수 데이터가
별도의 js파일로 분리해서 사용 가능!
export const FOOTER_INFO_LIST = [
{ id: 1, link: 'https://github.com/terms', text: 'Terms' },
{ id: 2, link: 'https://github.com/privacy', text: 'Privacy' },
...
{ id: 11, link: 'https://github.com/about', text: 'About' },
];
백엔드 API가 미완성인 상황에서 Mock Data를 사용하지 않는다면
Mock Data는 실제 서버에서 보내주는 데이터 형식과 동일해야 하기 때문에 .json(JSON형식)파일로 데이터를 생성해야 함.
실제 데이터 형태와 맞게 객체or배열 안에 가짜 데이터 구성!
백엔드 개발자와 소통해 key-value 값을 동일하게 맞추어 추후 실제 API 통신을 원활하게 가능하도록 하자.
마켓컬리 추천 상품 리스트
동일한 형태의 data 나열이기 때문에 '배열'로 관리
// public/data/recommendData.json
[
{
"id": 1,
"name": "[돈마루] 한돈 삼겹살 2종 (냉장)",
"discount_rate": 5,
"discounted_price": 12967,
"original_price": 13650,
"is_sold_out": false
},
{
"id": 2,
"name": "엔다이브 2~3입",
...
},
...
]
상세페이지
동일 형태 데이터 나열이 아닌 한 상품의 데이터라서 '객체'로 관리
// public/data/productData.json
{
"id": 3,
"image_url": "https://img-cf.kurly.com/shop/data/goods/1648203571907l0.jpg",
"name": "[콜린스그린] 더 오렌지 1000mL",
"short_description": "물 한방울 넣지 않고 순수한 오렌지 과육을 짜낸 100% 착즙 오렌지 주스",
"discounted_price": 14080,
"discount_rate": 20,
"original_price": 17600,
"unit_text": "1병",
"weight": "1000ml",
"delivery_type": [
{ "id": 0, "text": "샛별배송" },
{ "id": 1, "text": "택배배송" }
],
...
}
Mock Data는 로컬 서버에서 받도록 구현해야 함.
그래서 npm start시 로컬서버에 올라가는 폴더인 public의 하위 폴더로 관리.
public
└── data
├── recommendData.json
├── productData.json
└── ...
Mock Data는 실제 데이터와 동일하게 fetch 메서드로 호출
fetch('http://localhost:3000/data/recommendData.json')
/data 앞의 주소는 생략 권장.
fetch('/data/recommendData.json', {
method: 'GET' //GET일 경우 생략 가능.
}).then(res => res.json())
//json 데이터 -> 자바스크립트 객체 형태로 변환
.then(data => {
setProductList(data);
//변환된 데이터 -> ProductList state 값으로 업데이트
});
추천리스트 data : 페이지 불러올 때
상세페이지 data : 클릭 시
useEffect(() => {
fetch('/data/recommendData.json', {
method: 'GET'
})
.then(res => res.json())
.then(data => {
setProductList(data);
});
},[]);//추천 리스트는 최초 렌더링 시 불러오기.
전체 코드
// RecommendList.js
import React, { useState, useEffect } from 'react';
import ProductCard from './ProductCard/ProductCard';
import './RecommendList.scss';
const RecommendList = () => {
const [productList, setProductList] = useState([]);
useEffect(() => {
fetch('/data/recommendData.json', {
method: 'GET'
})
.then(res => res.json())
.then(data => {
setProductList(data);
});
},[]);
return (
<div className="recommendList">
<h1>이 상품 어때요?</h1>
<div className="listWrapper">
{productList.map(product => {
return (
<ProductCard
key={product.id}
product={product}
/>
);
})}
</div>
</div>
);
}
export default RecommendList;
🪓 fetch 메서드는 꼭 useEffect와 같이 사용 안해도 됨.
특정 태그 클릭 시 데이터를 호출하고 싶으면 이벤트함수 내에 fetch써도 ㄱㅊ
예) 리스트 상품 하나 클릭하면 전체 커멘트 리스트 숨겨버리고 해당하는 상세페이지 나오도록 구현해도 ㄱㅊ을듯?