쇼핑몰프로젝트(7)-장바구니 페이지 만들기

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

(Cart.js)

function Cart() {
  const cartItems = useSelector((state) => state.cart);
  const dispatch = useDispatch();

  const calculateTotal = () => {
    return cartItems.reduce((acc, item) => acc + item.price * item.quantity, 0);
  };

  return (
    <div className="cart-container">
      {cartItems.map((item) => (
        <div className="cart-item">
          <input
            type="checkbox"
            checked={item.selected}
            onChange={() => dispatch(toggleSelection(item.id))}
          />
          <img src={item.imageUrl} className="product-image" />
          <span className="product-name">{item.name}</span>
          <span className="product-price">{item.price}원</span>
          <div className="quantity-controls">
            <button onClick={() => dispatch(decreaseQuantity(item.id))}>
              -
            </button>
            <input
              type="number"
              value={item.quantity}
              readOnly
              className="product-quantity"
            />
            <button onClick={() => dispatch(increaseQuantity(item.id))}>
              +
            </button>
          </div>
          <button onClick={() => dispatch(removeItem(item.id))}>삭제</button>
        </div>
      ))}
      <div className="cart-actions">
        <button onClick={() => dispatch(removeSelectedItems())}>
          선택 삭제
        </button>
        <button onClick={() => dispatch(removeAllItems())}>전체 삭제</button>
        <button>선택 상품 주문</button>
        <button>전체 상품 주문</button>
      </div>
      <div className="cart-summary">
        <div>주문 금액: {calculateTotal()}원</div>
        <div>배송비: 3000원</div>
        <div>합계: {calculateTotal() + 3000}원</div>
      </div>
      <button className="checkout">주문하기</button>
    </div>
  );
}
(store.js)

const cart = createSlice({
  name: "cart",
  initialState: [
    {
      id: 1,
      name: "보송보송타월",
      price: 7900,
      quantity: 1,
      selected: false,
      imageUrl:
        "https://raw.githubusercontent.com/mimkong/meongmeongdata/master/item1.jpg",
    },
    {
      id: 2,
      name: "선데이백",
      price: 169000,
      quantity: 2,
      selected: false,
      imageUrl:
        "https://raw.githubusercontent.com/mimkong/meongmeongdata/master/item2.jpg",
    },
  ],
  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 [];
    },
  },
});

export default configureStore({
  reducer: {cart: cart.reducer },
});
export const {
  toggleSelection,
  increaseQuantity,
  decreaseQuantity,
  removeItem,
  removeSelectedItems,
  removeAllItems,
} = cart.actions;

(redux 쓰기 전)

function Cart() {
  const [cartItems, setCartItems] = useState([
    {
      id: 1,
      name: "보송보송타월",
      price: 4900,
      quantity: 1,
      selected: false,
      imageUrl: "path_to_imageA.jpg",
    },
    {
      id: 2,
      name: "Product B",
      price: 20,
      quantity: 2,
      selected: false,
      imageUrl: "path_to_imageB.jpg",
    },
  ]);

  const toggleSelection = (id) => {
    const updatedCart = cartItems.map((item) =>
      item.id === id ? { ...item, selected: !item.selected } : item
    );
    setCartItems(updatedCart);
  };

  const increaseQuantity = (id) => {
    const updatedCart = cartItems.map((item) =>
      item.id === id ? { ...item, quantity: item.quantity + 1 } : item
    );
    setCartItems(updatedCart);
  };

  const decreaseQuantity = (id) => {
    const updatedCart = cartItems.map((item) =>
      item.id === id && item.quantity > 1
        ? { ...item, quantity: item.quantity - 1 }
        : item
    );
    setCartItems(updatedCart);
  };
  const removeSelectedItems = () => {
    const updatedCart = cartItems.filter((item) => !item.selected);
    setCartItems(updatedCart);
  };

  const removeAllItems = () => {
    setCartItems([]);
  };

  const calculateTotal = () => {
    return cartItems.reduce((acc, item) => acc + item.price * item.quantity, 0);
  };

  return (
    <div className="cart-container">
      {cartItems.map((item) => (
        <div className="cart-item" key={item.id}>
          <input
            type="checkbox"
            checked={item.selected}
            onChange={() => toggleSelection(item.id)}
          />
          <img src={item.imageUrl} className="product-image" />
          <span className="product-name">{item.name}</span>
          <span className="product-price">{item.price}원</span>
          <div className="quantity-controls">
            <button onClick={() => decreaseQuantity(item.id)}>-</button>
            <input
              type="number"
              value={item.quantity}
              readOnly
              className="product-quantity"
            />
            <button onClick={() => increaseQuantity(item.id)}>+</button>
          </div>
          <button
            onClick={() =>
              setCartItems(cartItems.filter((ci) => ci.id !== item.id))
            }
          >
            삭제
          </button>
        </div>
      ))}
      <div className="cart-actions">
        <button onClick={removeSelectedItems}>선택 삭제</button>
        <button onClick={removeAllItems}>전체 삭제</button>
        <button>선택 상품 주문</button>
        <button>전체 상품 주문</button>
      </div>
      <div className="cart-summary">
        <div>주문 금액: {calculateTotal()}원</div>
        <div>배송비: 3000원</div>
        <div>합계: {calculateTotal() + 3000}원</div>
      </div>
      <button className="checkout">주문하기</button>
    </div>
  );
}
  • 처음부터 store.js에 저장하는 것은 아직 익숙하지가 않아 useState를 사용해서 틀을 먼저 잡았다.
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;
    }
  • if(item) 은 item이 undefined인지 아닌지 확인한다.
    만약 if문이 없다면 item이 undefined인 경우 item.selected에 접근할 때 "Cannot read properties of undefined" 라는 오류가 발생한다.

0개의 댓글