[React] ๐Ÿ‘Ÿ์ƒํ’ˆ ์ถ”๊ฐ€ํ•˜๊ธฐ ๊ธฐ๋Šฅ ๊ตฌํ˜„

์ด๋‹ค์˜ยท2024๋…„ 7์›” 9์ผ

React

๋ชฉ๋ก ๋ณด๊ธฐ
14/31

๊ธฐ๋Šฅ

Detail(์ƒํ’ˆ์ •๋ณด ํŽ˜์ด์ง€)์—์„œ ์ฃผ๋ฌธํ•˜๊ธฐ ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ Cart(์žฅ๋ฐ”๊ตฌ๋‹ˆ ํŽ˜์ด์ง€)์— ํ•ด๋‹น ์ƒํ’ˆ์ด ์ถ”๊ฐ€๋˜๋Š” ๊ธฐ๋Šฅ

Redux ์‚ฌ์šฉ

  • Redux๋Š” props ์—†์ด state๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค

์ „์ฒด ์ฝ”๋“œ

//store.jsx

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

const cart = createSlice({
  name: "cart",
  initialState: [ // ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ๋ณด์—ฌ์งˆ ๋ฐ์ดํ„ฐ๋“ค
    { id: 0, name: "White and Black", count: 2 }, 
    { id: 2, name: "Grey Yordan", count: 1 },
  ],
  reducers: {
 addItem(state, action) {
    const sameNumber = state.filter(num => {
        return num.id === action.payload.id; 
      });
     if (sameNumber.length) {
        alert("๋™์ผํ•œ ์ƒํ’ˆ์ด ์žˆ์Šต๋‹ˆ๋‹ค");
      } else {
        state.push(action.payload);
      }
    },
  },
});

export const { addItem } = cart.actions; // addItem ๋‚ด๋ณด๋‚ด๊ธฐ

export default configureStore({
  reducer: {
 cart: cart.reducer,
  },
});

๊ธฐ์กด state์™€ action.payload.id ๊ฐ’์„ ๋น„๊ตํ•ด์„œ ๊ฐ™์€ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๋ฐ˜ํ™˜ํ•œ ๊ฐ’์˜ ๊ธธ์ด์— ๋˜‘๊ฐ™์€ ์ƒํ’ˆ์ด ์žˆ๋‹ค๋ฉด ๋™์ผํ•œ ์ƒํ’ˆ์ด ์žˆ๋‹ค๊ณ  ์•Œ๋ฆผ์ฐฝ์„ ๋„์šฐ๊ณ  ๊ทธ๊ฒŒ ์•„๋‹ˆ๋ผ๋ฉด ์ƒํ’ˆ ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ธฐ๋Šฅ์ด๋‹ค

// Detail.jsx

const Detail = ({ shoes }) => {
  const { id } = useParams();
  const products = shoes.find((product) => product.id === parseInt(id));
  const dispatch = useDispatch();

  return(
  <div>
   <button
    className="btn btn-danger"
    onClick={() => {
     dispatch(
      addItem({
       id: products.id,
       name: products.title,
       count: 1,
       })
      );
     }}
    >
    ์ฃผ๋ฌธํ•˜๊ธฐ
  </button>
 </div>
 );
};

export default Detail;
  • ๋‹ค๋ฅธ ์ฝ”๋“œ๋ฅผ ์ƒ๋žตํ•˜๊ณ  ์ƒํ’ˆ์ถ”๊ฐ€ ๊ธฐ๋Šฅ๋งŒ ๋ณด์ž๋ฉด ์ฃผ๋ฌธํ•˜๊ธฐ ๋ฒ„ํŠผ์„ ํด๋ฆญํ–ˆ์„ ๋•Œ id๊ฐ’, ์ƒํ’ˆ๋ช…, ์ˆ˜๋Ÿ‰์ด ์žฅ๋ฐ”๊ตฌ๋‹ˆ ํŽ˜์ด์ง€์— ์ถ”๊ฐ€๊ฐ€ ๋˜์–ด์•ผ ํ•œ๋‹ค. ์œ„์— ์ฝ”๋“œ๋Š” ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ๋งž๊ฒŒ ์“ด ๊ฑฐ๊ธฐ ๋•Œ๋ฌธ์— ํ™”๋ฉด์—์„œ ์ž˜ ์ž‘๋™ํ•˜์ง€๋งŒ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ๋‹ค. ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ์•Œ ์ˆ˜ ์žˆ๋‹ค

โš ๏ธ ๋ฌธ์ œ ํ•ด๊ฒฐ

<button
  className="btn btn-danger"
  onClick={() => {
    dispatch(
      addItem({ //๋ฐ”๋กœ ์‹คํ–‰๋˜์ง€ ์•Š์Œ. store.jsx ํŒŒ์ผ์— ์š”์ฒญ
        `id: ${products.id},
        name: ${products.title},
        count: 1,`
      })
    );
  }}
>
  ์ฃผ๋ฌธํ•˜๊ธฐ
</button>;
  • addItem ํ•จ์ˆ˜๋กœ ๋ณด๋‚ธ ๋ฐ์ดํ„ฐ๊ฐ€ Templeate Literal ๋ฐฉ๋ฒ•์ธ ๋ฌธ์ž์—ด์ด์—ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ์ฒด๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ด์•ผ์ง€ const sameNumber = state.filter(num => { return num.id === action.payload.id; }); ์ด ์ฝ”๋“œ์ฒ˜๋Ÿผ filter๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋น„๊ต๊ฐ€ ๊ฐ€๋Šฅํ•ด์ง„๋‹ค. ์ฆ‰ ๋‚˜๋Š” aciton.payload.id๋ฅผ state๋ž‘ ๋น„๊ตํ•œ ๊ฒŒ ์•„๋‹ˆ๋ผ ๋ฌธ์ž์—ด id๋ฅผ ๋น„๊ตํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์žฅ๋ฐ”๊ตฌ๋‹ˆ ํŽ˜์ด์ง€์— ํ•ด๋‹น ์ƒํ’ˆ๋‚ด์—ญ์ด ๋ Œ๋”๋ง ๋˜์ง€ ์•Š์•˜๋˜ ๊ฒƒ์ด๋‹ค

์ถœ์ฒ˜

์ฝ”๋”ฉ์• ํ”Œ ๋ฆฌ์•กํŠธ

0๊ฐœ์˜ ๋Œ“๊ธ€