쇼핑몰프로젝트(8) - 장바구니

신혜원·2023년 9월 7일
0
post-thumbnail

장바구니에 상품 추가하기

원래 있던 상품이면 수량만 증가시키기

(Detail.js)

const isIdExistInCart = cartItems.some((item) => item.id == result?.id);

<button
            className="add-to-cart"
            onClick={() => {
              isIdExistInCart
                ? dispatch(increaseQuantity(result?.id))
                : dispatch(addItem(result));
              setShowModal(true);
            }}
          >
            장바구니 담기
          </button>
          <button className="buy-now">바로 구매하기</button>
        </div>
      </div>
      {showModal && <CartModal onClose={() => setShowModal(false)} />}
    </>
  • some 메서드는 true or flase를 내놓는다.
    이를통해 result.id 의 값과 item.id가 같은지 확인하여 true 혹은 false 를 isIdExistInCart 에 저장한다.
  • 삼항연산자를 통해 true면 result.id를 dispatch를 통해 increaseQuantity로 보내고 false면 result를 addItem에 보낸다.
    여기서 주의할 점은 addItem에는 상품의 정보 전체가 들어가야하기 때문에 result를 넣지만
    increaseQuantity에서는 action.payload가 item.id와 같은지 확인되기 때문에 같은 객체를 넣어야한다. 따라서 result.id를 넣은 것이다.
(CartModal.js)

function CartModal({ onClose }) {
  const navigate = useNavigate();
  return (
    <div className="cart-modal">
      <div className="cart-modal-content">
        <p>장바구니에 상품이 정상적으로 담겼습니다.</p>
        <button
          onClick={() => {
            navigate(`/cart`);
          }}
        >
          장바구니 보기
        </button>
        <button onClick={onClose}>쇼핑 계속하기</button>
      </div>
    </div>
  );
}
addItem: (state, action) => {
    state.push(action.payload);
}
  • Redux Toolkit에서는 Immer라이브러리가 내장되어있어,
    배열이나 객체의 불변성을 직접 처리할 필요 없이 마치 mutable(가변) 한 것처럼 작성할 수 있다.
    즉, 기존의 JS배열 메소드 중 불변성을 지키지 않는 메소드들을(ex. push, splice 등) 사용해도 무방하다.

  • state.push(action.payload)와 같이 push 메소드를 사용할 경우 값을 반환하지 않아도 된다.
    Immer가 자동으로 변경을 감지하고 새로운 상태를 반환하기 때문이다. (return이 포함되어있다고 생각하면 편할듯...?)

  • 그래서 state.push할때에는 reuturn을 사용하지 않고 직접state를 변경하면 된다.

  • 요약: state를 직접 변경하는 메소드들을 사용할 때에는 반환 값이 필요하지 않다.
    그러나 새로운 배열이나 객체를 반환하는 메소드들을 사용할 때에는 값을 반환해야한다.


(store.js)
const cart = createSlice({
  name: "cart",
  initialState: [],
  reducers: {
    toggleSelection: (state, action) => {
      const item = state.find((item) => item.id === action.payload);
      if (item) {
        item.selected = !item.selected;
      }
    },
    increaseQuantity: (state, action) => {
      const item = state.find((item) => item.id === action.payload);
      if (item) {
        item.quantity += 1;
      }
    },
    decreaseQuantity: (state, action) => {
      const item = state.find((item) => item.id === action.payload);
      if (item && item.quantity > 1) {
        item.quantity -= 1;
      }
    },
    removeItem: (state, action) => {
      return state.filter((item) => item.id !== action.payload);
    },
    removeSelectedItems: (state) => {
      return state.filter((item) => !item.selected);
    },
    removeAllItems: () => {
      return [];
    },
    addItem: (state, action) => {
      state.push(action.payload);
    },
  },
});

redux를 사용해서 체크리스트 체크, 수량감소/증가, 아이템 제거, 선택아이템제거, 전체제거 함수를 만든 후 각 버튼마다 함수를 사용하여 cart의 state를 변경하게 만들었다.

0개의 댓글