App.jsx
const [cart, setCart] = useState([]); //장바구니
App.jsx에서 장바구니 개수를 표시할 cart useState를 생성한다.
그리고 Navbar컴포넌트에 cartCount로 cart 배열안의 개수를 props로 전달한다.
<Navbar user={user} cartCount={cart.length} />
Navbar.jsx
const Navbar = ({ user, cartCount }) => {
App.jsx에서 전달받은 props로
장바구니에 표시한다.
<NavLink to="/cart" className="align_center">
장바구니 <p className="align_center cart_counts">{cartCount}</p>
</NavLink>
그리고 장바구니에 상품을 담을 수 있는 함수를 추가한다.
//장바구니에 상품 추가
const addToCart = (product, quantity) => {
//기존의 카트 데이터 뒤에 새로운 데이터 추가
setCart([...cart, { product, quantity }]);
};
라우팅 컴포넌트에 만든 함수 전달한다.
return (
<div className="app">
<Navbar user={user} cartCount={cart.length} />
<main>
<Routing addToCart={addToCart} />
</main>
</div>
);
Routing.jsx에서 SingleProductPage에 props로 함수 전달
const Routing = ({ addToCart }) => {
return (
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/products" element={<ProductsPage />} />
<Route
path="/product/:id"
element={<SingleProductPage addToCart={addToCart} />}
/>
<Route path="/signup" element={<SignupPage />} />
<Route path="/login" element={<LoginPage />} />
<Route path="/cart" element={<CartPage />} />
<Route path="/myorders" element={<MyOrderPage />} />
<Route path="/logout" element={<Logout />} />
</Routes>
);
};
SingleProductPage.jsx
const SingleProductPage = ({ addToCart }) => {
props로 addTocart 함수 받아와서
장바구니를 클릭할 때마다 실행하도록 onclick 이벤트를 추가한다.
<button
onClick={() => addToCart(product, quantity)}
className="search_button add_cart"
>
장바구니 추가
</button>
하지만 같은 제품의 경우에도 계속 장바구니가 추가되는 현상이 발생함 .
이러한 현상을 방지하기 위해서
//장바구니에 상품 추가
const addToCart = (product, quantity) => {
const updatedCart = [...cart]; //기존의 카트
//findIndex는 모든 배열아이템과 비교해서 참이 있으면 true를 리턴하고 없으면 -1
const productIndex = updatedCart.findIndex(
(item) => item.product._id === product._id
);
if (productIndex === -1) {
updatedCart.push({ product: product, quantity: quantity });
} else {
updatedCart[productIndex].quantity += quantity;
}
setCart(updatedCart);
};
이미 같은 제품이 장바구니에 들어가있을 경우 장바구니 추가를 눌러도 장바구니 개수가 늘어나지않는다.
장바구니 cart에 새 제품과 수량을 업데이트 하는 요청을
포스트맨에서 테스트한다.
http://localhost:5000/api/cart/1
import apiClient from "./api-client";
//axios의 헤더에 토큰을 추가한다.
const setAuthToken = (token) => {
if (token) {
apiClient.defaults.headers.common["x-auth-token"] = token;
} else {
delete apiClient.defaults.headers.common["x-auth-token"];
}
};
export default setAuthToken;
App.jsx에서 설정함
setAuthToken(localStorage.getItem("token"));
function App() {
servies 폴더 안에 cartServices.js 파일을 생성한다.
import apiClient from "../utils/api-client";
//카트에 제품 id와 수량을 추가하는 요청
export function addToCartAPI(id, quantity) {
return apiClient.post(`/cart/${id}`, { quantity });
}
mongoDb확인 시 Array의 개수는 증가하지 않았고,
quantity 개수만 업데이트됨을 확인 할 수 있다.
'FRONTEND > React' 카테고리의 다른 글
[myCart] 유저 컨텍스트(UserContext), 장바구니 컨텍스트(CartContext) 적용 (0) | 2023.12.21 |
---|---|
[myCart] react-toastify 라이브러리 사용으로 카트 추가 시 메세지 출력 (0) | 2023.12.21 |
[myCart] App에서 토큰 정보로 유저 관리/ 네브바 메뉴를 로그인 상태에 따라서 다르게 보여주기/로그아웃 (0) | 2023.12.21 |
[myCart] 로그인 페이지/JWT 토큰 발급과 로컬스토리지에 토큰 저장 후 홈페이지로 이동 (0) | 2023.12.21 |
[myCart] signup에러 출력 (0) | 2023.12.21 |