본문 바로가기
교육후 개인공부/React

[Next.js] 리덕스와 장바구니기능

by 뭉지야 2024. 4. 12.
728x90

쇼핑몰사이트 거의 마무리된것 같다.

장바구니 기능 구현완료다!!!!

 

store.js

import { createSlice, configureStore } from "@reduxjs/toolkit";

const initialState = {
  value: {
    email: "snrnsi",
    pw: "123",
  },
};

const LoginState = createSlice({
  name: "login",
  initialState,
  reducers: {
    //로그인한 유저 변경되는게 들어가야한다.
    setLogin: (state, action) => {
      state.user = action.payload;
    },
    setLogout: state => {
      state.email = null;
      state.pw = null;
    },
  },
});
const CartState = createSlice({
  name: "cart",
  initialState: [
    {
      id: 1,
      product: "홍해인자켓",
      price: "20000",
      count: 1,
    },
    {
      id: 6,
      product: "티모시자켓",
      price: "20000",
      count: 1,
    },
  ],
  //initialState를 수정해주는 함수이다
  reducers: {
    //장바구니에서추가, 리스트페이지랑연결
    addcart: (state, action) => {
      //state.push(action.payload);
      const common = state.findIndex(
        el => el.product === action.payload.product
      );
      {
        common === -1 ? state.push(action.payload) : state[common].count++;
      }
    },
    //장바구니에서삭제
    deletecart: (state, action) => {
      state.pop(action.payload);
    },

    countUp: (state, action) => {
      //cart에서 수량 조절하는 것 , 플러스
      state[action.payload].count++;
      //console.log(Item);
    },
    countDown: (state, action) => {
      //cart에서 수량 조절하는 것, 마이너스
      state[action.payload].count--;
    },
  },
});

export const { setLogin, setLogout } = LoginState.actions;
export const { addcart, deletecart, countUp, countDown } = CartState.actions;

export default configureStore({
  reducer: {
    loginState: LoginState.reducer,
    cartState: CartState.reducer,
  },
  devTools: true,
});

 

Provider.js

"use client";

import { Provider } from "react-redux";
import store from "./store";

export default function ReduxProvider({ children }) {
  return <Provider store={store}>{children}</Provider>;
}

 

/list/page.js

리스트페이지의 각 물품의 장바구니버튼을 누르면 장바구니에 담기고 cart페이지로 이동하게 구현했다.

"use client";

import { useState } from "react";
import { useRouter } from "next/navigation";
import ListLeft from "../ListLeft";
import { productData } from "@/util/productData";
import { useDispatch, useSelector } from "react-redux";
import { addcart } from "@/redux/store";

export default function List() {
  let router = useRouter();
  const dispatch = useDispatch();
  //const value2 = useSelector(state => state.CartState);
  // console.log(value2);

  //let [수량, 수량변경] = useState([2, 2, 2, 2, 2, 2, 2, 1, 1]);
  const handleClick = (id, product, count, price) => {
    dispatch(addcart({ id, product, count, price })); //여기에 id가 들어오면 이게 payload다. 여기서 넘겨주는것만 item에서 받을수있다
    //console.log(value2);
    // console.log({ i });
    //여기서 보낸 id랑 product가
    router.push("/cart");
  };
  //console.log(productData);
  return (
    <div>
      <h2 className="title">상품목록</h2>

      <div className="merchandise">
        <div className="list-left">
          <ListLeft />
        </div>
        <div className="list-right">
          <div className="goods">
            {productData.jacket.map((a, i) => {
              return (
                <div className="food" key={i}>
                  <img src={`/jacket${i + 1}.png`} className="food-img" />
                  <h4>{productData.jacket[i].product}</h4>
                  <h4>{productData.jacket[i].price}원</h4>
                  <button
                    onClick={() =>
                      handleClick(a.id, a.product, a.count, a.price)
                    }
                  >
                    장바구니
                  </button>
                </div>
              );
            })}
            {productData.shoe.map((a, i) => {
              return (
                <div className="food" key={i}>
                  <img src={`/shoe${i + 1}.png`} className="food-img" />
                  <h4>{productData.shoe[i].product}</h4>
                  <h4>{productData.shoe[i].price}원</h4>
                  <button
                    onClick={() =>
                      handleClick(a.id, a.product, a.count, a.price)
                    }
                  >
                    장바구니
                  </button>
                </div>
              );
            })}
          </div>
        </div>
      </div>
    </div>
  );
}

 

리덕스는 client component에서만 쓸수있기때문에

cart/page.js에다가 Item이라는 컴포넌트를 만들었다.

 

Item.js

"use client";

import { countUp, countDown, deletecart } from "@/redux/store";
import { useState, useEffect } from "react";
import { useSelector, useDispatch } from "react-redux";
import { useRouter } from "next/navigation";

export default function Item() {
  let router = useRouter();
  const Item = useSelector(state => state.cartState);
  const dispatch = useDispatch();

  const handleUp = i => {
    dispatch(countUp(i));
  };
  const handleDown = i => {
    dispatch(countDown(i));
  };
  const handleDelete = i => {
    dispatch(deletecart(i));
  };

  return (
    <div>
      <h2 className="title">Test Cart</h2>
      {Item.map((a, i) => {
        return (
          <div className="cart-item" key={i}>
            {/* <p>{a.id}</p> */}
            <p>{a.product}</p>
            <p>{a.price}</p>
            <button onClick={() => handleUp(i)}>+</button>
            <p>{a.count}</p>
            <button onClick={() => handleDown(i)}>-</button>
            <button onClick={() => handleDelete(i)}>삭제</button>
          </div>
        );
      })}
    </div>
  );
}

 

 

액션생성함수를 구현하는 부분에서 어려움을 많이 느꼈다.

계속 구글링해가며 콘솔찍어가면서 차근차근해보니까 해결됬다!!!!!

결국 리덕스는 계속 경험해보고 자꾸 이용해봐야 익숙해질것같다!!

728x90

'교육후 개인공부 > React' 카테고리의 다른 글

[React] Suspense  (0) 2024.04.03
[Next.js] 리덕스와 자체 로그인연결  (0) 2024.04.03
[Next.js] Oauth와 자체 로그인 같이 구현  (0) 2024.03.23
[React] useCallback  (0) 2024.03.19
[React] useMemo  (0) 2024.03.19