반응형
약간 코드 따라치기를 하게 된 것 같기는 한데 ..
중간 중간 생긴 에러들 잘 수정했다
action id 대신 item을 비교해야 하는 경우들이 꽤 있었다.
Cart.js
import React, { useContext } from 'react';
import styles from './Cart.module.css';
import Modal from '../UI/Modal';
import CartContext from '../../store/cart-context';
import CartItem from './CartItem';
const Cart = props => {
const cartCtx = useContext(CartContext);
const totalAmount = `$${cartCtx.totalAmount.toFixed(2)}`;
const hasItems = cartCtx.items.length > 0;
const cartItemRemoveHandler = (id) => {
cartCtx.removeItem(id);
}
const cartItemAddHandler = (item) => {
cartCtx.addItem({ ...item, amount: 1 });
}
const cartItems = <ul className={styles['cart-items']}>
{cartCtx.items.map((item) =>
<CartItem key={item.id} name={item.name} amount={item.amount} price={item.price}
onRemove={cartItemRemoveHandler.bind(null, item.id)}
onAdd={cartItemAddHandler.bind(null, item)} />
)}
</ul>;
return <Modal onClose={props.onClose}>
{cartItems}
<div className={styles.total}>
<span>Total Amount</span>
<span>{totalAmount}</span>
</div>
<div className={styles.actions}>
<button className={styles['button--alt']} onClick={props.onClose}>Close</button>
{hasItems &&
<button className={styles.button}>Order</button>
}
</div>
</Modal>
}
export default Cart;
CartProvider.js
import CartContext from './cart-context';
import { useReducer } from 'react';
const defaultCartState = {
items: [],
totalAmount: 0
}
const cartReducer = (state, action) => {
if (action.type === 'ADD') {
const exisitingCartItemIndex = state.items.findIndex(item => item.id === action.item.id);
const exisitingCartItem = state.items[exisitingCartItemIndex];
let updatedItem;
let updatedItems = state.items.concat(action.item);
if (exisitingCartItem) {
updatedItem = {
...exisitingCartItem,
amount: exisitingCartItem.amount + action.item.amount
};
updatedItems = [...state.items];
updatedItems[exisitingCartItemIndex] = updatedItem;
} else {
updatedItems = state.items.concat(action.item);
}
const updatedTotalAmount = state.totalAmount + action.item.price * action.item.amount;
return {
items: updatedItems,
totalAmount: updatedTotalAmount
}
} else if (action.type === 'REMOVE') {
console.log('something');
const existingCartItemIndex = state.items.findIndex(item => item.id === action.item);
const existingItem = state.items[existingCartItemIndex];
const updatedTotalAmount = state.totalAmount - existingItem.price;
let updatedItems;
if (existingItem.amount === 1) {
console.log('this');
console.log(action.item);
updatedItems = state.items.filter(item => item.id !== action.item);
} else {
const updatedItem = { ...existingItem, amount: existingItem.amount - 1 };
updatedItems = [...state.items];
updatedItems[existingCartItemIndex] = updatedItem;
}
return {
items: updatedItems,
totalAmount: updatedTotalAmount
};
}
return defaultCartState;
}
const CartProvider = props => {
const [cartState, dispatchCartAction] = useReducer(cartReducer, defaultCartState);
const addItemToCartHandler = item => {
dispatchCartAction({ type: 'ADD', item: item });
};
const removeItemFromCartHandler = id => {
dispatchCartAction({ type: 'REMOVE', item: id });
};
const cartContext = {
items: cartState.items,
totalAmount: cartState.totalAmount,
addItem: addItemToCartHandler,
removeItem: removeItemFromCartHandler
};
return <CartContext.Provider value={cartContext}>
{props.children}
</CartContext.Provider>
}
export default CartProvider;
반응형
'온라인 강의 > React 완벽 가이드 [Udemy]' 카테고리의 다른 글
160. 모듈 소개 [섹션 12] (0) | 2023.06.23 |
---|---|
158. useEffect 훅 사용하기 (0) | 2023.06.22 |
156. 더 복잡한 리듀서 로직 작업하기 (0) | 2023.06.22 |
155. 장바구니 항목 출력하기 (0) | 2023.06.22 |
154. Refs 및 Forward Refs 작업하기 (0) | 2023.06.16 |