Mock Data를 활용한 여러개의 피드 구현 과제
오늘 해결한 개념이 휘발되기 전에 기록하는 글이다.
Mock Data란?
프론트엔드 개발을 진행하다 보면, UI 구성에 필요한 백엔드 API가 완성되지 않은 상황에서 개발을 진행해야 할 경우 백엔드에서 API가 완성될 때까지 무작정 기다리는 게 아니라, 데이터가 들어오는 상황에 대비해 의도한 대로 UI가 구현되는지 확인을 위해 사용되는 데이터를 말한다.
즉, Mock Data란 실제 API에서 받아온 데이터가 아닌 프론트엔드 개발자가 필요에 의해 샘플로 만든 데이터이다.
Mock Data를 사용하는 이유
Mock Data 생성
Mock Data는 실제 서버에서 보내주는 데이터의 형식과 동일하게 만들어야 하기 때문에 .json 확장자 파일로 데이터를 생성한다. 이때 실제로 들어올 데이터의 형태에 맞게 객체 혹은 배열 안에 가짜 데이터를 구성하는데, 백엔드 개발자와 소통해 key-vaule값을 동일하게 맞추어 추후 실제로 API 통신을 원활하게 진행할 수 있도록 한다.
한 가지 예로 마켓컬리의 추천 상품 리스트는 동일한 형태의 상품 컴포넌트가 리스트로 나열되어있는 형태이기 때문에 배열로 각 상품의 데이터를 관리할 수 있도록 구성한다.
// 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를 생성해 피드 리스트 컴포넌트 안에 매개 변수로 넣어준다. (이때 따로 props를 쓰지 않고 디스트럭처링 기법으로 넣어준다.) 그리고 그 피드 리스트 컴포넌트를 메인 페이지에 임포트한다.
일단 이렇게 Mock Data를 사용하려면 실제 데이터와 동일하게 fetch 메서드에서 호출한다.
fetch 메서드의 첫 번째 인자로 http 요청을 보낼 API 주소를 받는데, 여기에 우리가 생성한 Mock Data의 주소를 입력한다.
fetch('/data/recommendData.json', {
method: 'GET'
})
두 번째 인자는 요청을 보낼 때의 옵션 객체를 전달하는 부분으로 서버로부터 데이터를 받아오는 GET 요청이기 때문에 method 옵션에 GET 이라고 명시한다.(method가 GET인 경우엔 생략 가능)
fetch('/data/recommendData.json', {
method: 'GET'
})
.then(res => res.json())
.then(data => {
setProductList(data);
});
이후 JSON 형태의 response 데이터를 자바스크립트 객체 형태로 바꾸어준 다음, 받아온 데이터를 화면에 그려주기 위해 productList state를 업데이트 해준다.
호출 시점
fetch 메서드를 통해 Mock Data를 받아오는 시점은 실제로 데이터를 불러오는 시점이 언제인지에 따라 다르다. 버튼을 클릭했을 때 받아와야 하는 경우와, 페이지를 불러올 때 바로 화면에 그려줘야 하는 경우도 있다.
useEffect(() => {
fetch('/data/recommendData.json', {
method: 'GET'
})
.then(res => res.json())
.then(data => {
setProductList(data);
});
},[]); // 현재 예시에서는 페이지를 불러올 때 바로 화면에 그려줘야 하기 때문에 useEffect hook을 통해 컴포넌트가 마운트(최초로 화면에 그려짐)된 후 한 번만 데이터를 받아오도록 한다.
컴포전트를 메인 페이지에 뿌려주기 위해서 메인 function에 state를 언하고, fetch 함수로 불러올 데이터 주소를 넣어준다. fetch 함수는 첫번째 인자로 http 요청을 보낼 API 주소, 두번째로는 요청을 보낼 때의 옵션들을 객체형태로 받는다. 보통 localhost:3000으로 넣어주지만 그렇게되면 포트번호가 변경될 경우가 생길 수 있어 생략하고 적는게 일반적이다.
요청을 받을 때 json 형태로 바꾸어주는데 json 을 쓰는 이유는 프론트엔드와 백엔드에서 서로 다른 언어로 통신하므로 우리가 갖는 객체랑 파이썬의 딕셔너리 자료형과 같지 않다. 그래서 둘 다 같은 형태로 볼 수 있게 json 파일로 바꾸어 준다. 통신할 때에는 string 형태로 전달하고, fetch 함수는 비동기이므로 then 메서드를 이용해 다음 작업을 진행한다.
map으로 배열 요소 하나하나를 돌며 그 데이터를 함수로 뽑아내서 자식 컴포넌트 Feed에 전달한다.
이때 List 데이터의 고유한 값인 id를 key 값으로 전달하며 배열의 index를 따로 빼서 전달하지 않는다.
key를 지정해야하는 이유는 다양한다.
리액트에서는 key값이 동일할 경우, 동일한 DOM Element 를 보여주기 때문에 댓글 추가, 삭제등의 기능을 구현할 때 적절하지 않다.
map method를 쓸 때에는 List 데이터에서 unique한 값을 key로 사용한다. 보통 database의 id로 사용하는데, id 값이 없다면 global 변수를 이용해 id를 생성하고 이를 key로 사용할 수 도 있다.
나 같은 경우에는 uuidv4 라는 key값을 사용했는데, 이렇게 유니크한
key값이 필요한 경우 유용하다.
uuid 는 소프트웨어 구축에 쓰이는 식별자 표준이다.
uuidsms 32개의 16진수로 표현되며 총 36개의 문자로 된 8-4-4-4-12라는 5개의 그룹을 하이픈으로 구분된다고 한다. id 값이 중복될 확률이 거의 없어 이러한 이유로 UUID를 데이터베이스의 프라이머리 키(primary key)로 종종 사용한다.
밑은 위스타그램 클론코딩 Main 페이지 상단이다.
{...feed} 스프레드 연산자를 사용해서 피드나 댓글 구현 할 때 쓰고있는데
map 함수 쓰는법을 더 많이 익혀야 겠다고 생각했던 과제였던 것 같다. 자바스크립트 기본지식이 많이 부족하다 보니까 항상 쓰는 것만 쓰고 과제에 나온 것 밖에 모르다보니 코드를 짜면서도 온전히 이해하지 못하고 쓰는 것들이 많다.