React redux로 장바구니 기능 구현

제이·2025년 12월 29일

React

목록 보기
3/3

문제상황 & 목표

  1. 상품의 '주문하기' 기능을 누름
  2. cartshoes.map에 상품 목록 추가 (같은 상품 id일 시 count 1씩 상승)

오류 과정은 캡처하지 않아서 첨부가 어렵지만 나같은 경우에는 추가하려는 cart의 상품 목록과
이미 불러오는 상품의 배열 양식이 맞지 않아 array에서 따로 양식을 찾는 과정에서 어려움을 겪은 점

data.js 상품 리스트 예시

let data = [
  {
    id: 0,
    title: "White and Black",
    img: "https://codingapple1.github.io/shop/shoes1.jpg",
    content: "Born in France",
    price: 120000,
  },

cart의 상품 목록 양식 예시

{ id: 0, name: "White and Black", count: 2 },

어찌저찌 주문하기 버튼을 눌러 console.log로 상품 배열이 출력되는 것을 확인했으나 이를 map에 어떻게 추가시킬지 고민했던 점이다.

시도해본 것

  1. store.jsx에서 따로 배열 객체를 추출하여 state.push를 시도했다.
(store.jsx)

addItem(state, action) {
      state.push({
          id: newItem.id,
          name: newItem.title, // reducer에서는 name으로 저장
          count: 1,
        });
    },
  1. detail.jsx에서 findproduct로 상품 id를 찾았던 점을 이용해 따로 findproductredux를 추가했으나 중복 선언 금지로 인해 철회했다.
 <button
              className="btn btn-danger"
              onClick={() => {
                dispatch(
                  addItem({
                    id,
                    title: findProduct.title,
                    count: 1,
                  })
                );
                console.log(addItem);
              }}
            >

해결한 방법

각종 시도가 통하지 않자, 구글링한 결과 같은 중복 아이디 상품이 중첩되어 map이나 배열에서 제대로 추가되지 않았던 점을 확인했다.

이에 따라 상품 id를 수정 및 중첩되는 경우 map 배열에 추가하는 대신 count를 1씩 증가시키기 위해 추가로 if문 코드를 작성했다.

(store.js)

let shoes = createSlice({
  name: "shoes",
  initialState: [
    { id: 0, name: "White and Black", count: 2 },
    { id: 2, name: "Grey Yordan", count: 1 },
  ],
  reducers: {
    addItem(state, action) {
      const newItem = action.payload; // { id, title }
      const found = state.find((item) => item.id === newItem.id);
      if (found) {
        found.count += 1; // 이미 있으면 count 증가
      } else {
        state.push({
          id: newItem.id,
          name: newItem.title, // reducer에서는 name으로 저장
          count: 1,
        });
      }
    },
  },
});

export let { addItem } = shoes.actions;

그리고 Detail.js에선 dispatch(addItem()) 안에 추가하려는 상품 배열 객체 코드를 다시 작성했다.

(Detail.js)

import { addItem } from "./store.jsx";
import { useDispatch, useSelector } from "react-redux";

function Detail(props) {
  let dispatch = useDispatch();
...

 <button
              className="btn btn-danger"
              onClick={() => {
                dispatch(
                  addItem({
                    id: findProduct.id,
                    title: findProduct.title,
                    count: 1,
                  })
                );
                console.log(addItem);
              }}
            >
              주문하기
            </button>

확인 시 정상적으로 cart에 상품 목록이 추가되는 것을 확인했다.

이전

수정 후

추가 기능 구현 : cart 삭제 기능 만들기

store.jsx에서 다시 새로운 함수를 만들었다. splice로 삭제하는 방법이 있었으나, 배열 자체를 직접 수정하기 보단 state.filter를 통해 배열을 반환하여 삭제할 id를 찾아 삭제하는 코드를 작성하기로 했다.

(store.js)

let shoes = createSlice({
  name: "shoes",
  initialState: [
    { id: 0, name: "White and Black", count: 2 },
    { id: 2, name: "Grey Yordan", count: 1 },
  ],
  reducers: {
    deleteItem(state, action) {
      const idToDelete = action.payload; // 삭제할 아이템 id
      return state.filter((item) => item.id !== idToDelete);
    },
  },
});

export let { deleteItem } = shoes.actions;

그리고 Cart.jsx에서 삭제 버튼 코드를 작성했다.

(Cart.jsx)

import { deleteItem } from "./store.jsx";

function Cart() {
  let shoes = useSelector((state) => state.shoes);
  let dispatch = useDispatch();
  console.log(shoes);
...

<button onClick={() => {dispatch(deleteItem(index));}}>삭제</button>

정상적으로 코드가 작성하는 것을 확인했다.

이전

삭제 기능 구현 확인

해당 TIL은 코딩애플(https://codingapple.com/)님의 강좌를 참고하여 공부한 내용을 토대로 작성되었음을 밝힙니다.

profile
배운 것을 기록합니다.

0개의 댓글