[React] Data 활용

JH Cho·2022년 9월 5일
0

React

목록 보기
10/27

정의

상수 데이터

상수 데이터 : 변하지 않는 정적인 데이터

예 ) 페이지를 구성할 때 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>

선언 위치

컴포넌트 파일 내부에서 선언

상수 데이터가 해당 컴포에서만 사용되고 가독성을 해치지 않을 때는~

  • state, props 등 리렌더링 때 변하는 값을 포함하는 상수 데이터는 컴포 내부에
  • 리렌더링 때마다 새로 선언, 할당 필요 없는 상수 데이터는 컴포 외부에.

예) 위에서 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' },
];

Mock Data

정의

Mock Data?

  • Mock Data란 실제 API에서 받아온 데이터가 아닌 프론트엔드 개발자가 필요에 의해 샘플로 만든 데이터
  • 왜? 백엔드 API가 미완성인 상태에서 개발을 진행해야 할때

Mock Data를 사용하는 이유

백엔드 API가 미완성인 상황에서 Mock Data를 사용하지 않는다면

  • 대부분은 실제 데이터가 들어올 부분들을 하드코딩으로 대체하고 작업을 진행하게 될 것
  • 백엔드 API가 완성되고 실제 데이터 반영 작업 시 어려움
  • 실제 데이터에는 존재하지 않는 값을 UI로 그렸거나
  • 반대로 실제 데이터 기반으로 작업해야 할 내용이 누락 될 위험

Mock Data의 장점

  • 백엔드 API가 미완성인 상태에서도 차질없이 개발 ㅇㅋ
  • 백엔드 API 구성을 미리 맞춰보기 ㅇㅋ
  • 실제로 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 활용

호출

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써도 ㄱㅊ

예) 리스트 상품 하나 클릭하면 전체 커멘트 리스트 숨겨버리고 해당하는 상세페이지 나오도록 구현해도 ㄱㅊ을듯?

profile
주먹구구식은 버리고 Why & How를 고민하며 프로그래밍 하는 개발자가 되자!

0개의 댓글