[TIL] Day50 #상태관리 # Cmarket Hooks

tnqls1211v·2022년 7월 6일
0

TIL

목록 보기
50/72
post-thumbnail

[TIL] Day50

2022.07.05(Tues)

[TIL] Day50
[SEB FE] Day49

☑️ FE-dev 상태관리

  • 상태: UI에 동적으로 표현될 데이터
    1. 로컬: 특정 컴포넌트 안에서만 관리되는 상태
      a. 다른 컴포넌트와 데이터 공유 X form data
         (ex. input box, select box … 입력값 받는 경우 해당)
    2. 전역: 프로덕트 전체 혹은 여러 컴포넌트에서 관리되는 상태
      (다른 컴포넌트와 상태를 공유하고 영향을 끼치는 상태) (ex. 로딩중 상태 …)
      👉 전역상태관리 Case: 라이트/다크모드 테마 설정, Globalization(국제화) 설정, Undo/Redo를 위한 History 기능
  • Side Effect: 함수 / 컴포넌트 입력 외에도 함수의 결과에 영향을 미치는 요인 (ex. 네트워크 요청, API 호출)
    ✋ Side Effect를 최대한 배제하고 컴포넌트 만들기!

✘ 서로 ‘다른’ 컴포넌트가 사용하는 상태의 종류가 ‘다르면', 꼭 젼역 상태일 필요 ❌ → 출처가 달라도 ok
✘ 서로 ‘다른' 컴포넌트가 ‘동일한’ 상태를 다룬다면, 출처(source)는 오직 한 곳이어야 함!
✚ 하나의 출처 = 전역 공간
🙌 한 곳에서만 상태를 저장하고 접근하기!


📎 전역 상태에서의 데이터 무결성

😈 데이터 무결성이란?
: 데이터 정확성 보장을 위해 데이터 변경에 제한을 두어 안정성을 저해하는 요소를 막고,
데이터 상태들을 항상 옳게 유지하는 것


무결성을 위한 방법론

Single source of truth(신뢰할 수 있는 단일 출처 원칙)
: 동일한 데이터는 항상 같은 곳에서 데이터를 가지고 온다.

상태 관리를 위한 Tool: React Context, Redux, MobX
⇒ 전역 상태 저장소 제공, Props drilling 이슈 해결

Props drilling이란?
: state가 필요없는 컴포넌트에서도 props로 자식 컴포넌트에게 넘겨줘야 하는 현상



☑️ [Pair] Cmarket Hooks

React Hooks을 사용하여 쇼핑몰 사이트의 장바구니 기능을 구현해보았다.
이번 과제를 통해 React 더 열심히 공부해야겠다구 다짐쓰..
기능 구현하는게 생각보다 쉽지 않았따..🫠
크게 기능은 1️⃣ 장바구니에 추가, 2️⃣ 장바구니에서 품목 삭제, 3️⃣ 수량 변경 3가지로 나눌 수 있다.

📁 폴더 구조

  • FE-SPRINT-CMARKET-HOOKS
    • /assets
      • state.js (dummy data)
    • /components
      • CarItem.js
      • Item.js
      • Nav.js
      • OrderSummary.js
    • /pages
      • ItemListContainer.js
      • ShoppingCart.js
    • App.js

  1. 장바구니에 추가 기능

    : ‘장바구니 담기’ 버튼 클릭시 이미 장바구니에 품목이 존재하면 수량만 증가하며, 존재하지 않으면 품목 자체를 추가하도록 구현

    function ItemListContainer({ items, cartItems, setCartItems }) {
      const handleClick = (e, id) => {
    	// '장바구니 담기' 버튼 클릭시 클릭한 해당 품목의 index
        const clickId = cartItems.findIndex((el) => el.itemId === id);
    
        if (clickId === -1) { // index가 존재하지 않으면 즉, 장바구니에 존재하지 않는다면
    	  // 기존 더미 데이터 배열에 새 객체 자체를 추가 (수량은 1로 고정)
          setCartItems([...cartItems, { itemId: id, quantity: 1 }]);
        } else { // 이미 장바구니에 index가 존재한다면
          cartItems[clickId].quantity += 1; // 수량 +1 증가
          setCartItems(cartItems);
        }
      };
    
      return (
        <div id="item-list-container">
          <div id="item-list-body">
            <div id="item-list-title">쓸모없는 선물 모음</div>
            {items.map((item, idx) => (
              <Item item={item} key={idx} handleClick={handleClick} />
            ))}
          </div>
        </div>
      );
    }

  1. 장바구니에서 품목 삭제 기능
    : 장바구니에서 해당 품목의 ‘삭제' 버튼 클릭시 장바구니에서 품목 자체가 삭제되도록 구현

    const handleDelete = (itemId) => { // 삭제 버튼 클릭시
    	// 장바구니에서 품목 체크 항목에서도 삭제
        setCheckedItems(checkedItems.filter((el) => el !== itemId));
    
    	// 장바구니 품목에서 삭제
        setCartItems(cartItems.filter((el) => el.itemId !== itemId));
      };

  1. 장바구니에서 품목 수량 변경 기능
    : 장바구니에 있는 품목들의 수량 변경이 되도록 구현
     (⬆️ 클릭시 수량 +1, ⬇️ 클릭시 수량 -1)
    const handleQuantityChange = (quantity, itemId) => {
         const result = [...cartItems];  // 장바구니 품목들을 복사해서 result 변수에 할당
     
     	// type='number'인 input box 우측의 ⬆️⬇️ 버튼 클릭시 해당 항목의 index
         const clickQuantity = cartItems.findIndex((el) => el.itemId === itemId);
         result[clickQuantity].quantity = quantity; // 1씩 증가/감소된 새로운 수량을 기존 수량에 할당
         setCartItems(result);  // 새로운 수량으로 변경된 품목으로 변경
       };


생각보다 추가, 수량 변경 기능 구현이 어려웠다..
🙈 추가 기능 구현시 변수 대소문자를 잘못써서 계속 console.log에 값이 찍히지 않는 문제로 시간을 많이 잡아먹었다. 🥲
🙉 수량 변경 구현시엔 무턱대고 carIItems 자체를 변경하려고 해서 생각한대로 숫자 인풋 박스 내용이 안 바뀌고, 콘솔창에서 인풋의 ⬆️ 버튼을 계속 클릭해도 값이 1만 증가되어 찍히는 현상이 발생해서 이 문제를 해결하는데 시간이 오래 걸렸다.. 해결 방법은 아래와 같다.

✍️ state 값을 직접 변경하게 되면 React는 이를 인지하지 못하고 재렌더링을 수행하지 않는다.
👉 그러므로, spread 연산자 혹은 Object.assign()으로 새로운 Object를 만들어 state를 복제한 후, 변경될 값을 담아주는 과정 필요!

0개의 댓글