Redux 5 : 버튼 클릭 시 장바구니에 상품 추가

qwe8851·2022년 10월 13일
0

💎 React

목록 보기
22/37

🤔 수량 +1 기능 만들기

1. 버튼 클릭 시 state를 +1 해주는 수정함수 만들기

let cart = createSlice({
  name : 'cart',
  initialState : [
    {id : 0, name : 'White and Black', count : 2},
    {id : 2, name : 'Grey Yordan', count : 1}
  ],
  reducers : {
    addCount(state, action){
      state[action.payload].count++
    }
  }
}) 

addCount라는 함수 생성

export해놓고 필요할 때 사용하면 됨
export let { addCount, addItem } = cart.actions

❗.payload
혼자 해볼 때 state[action.payload].count++ 부분에 .payload를 안붙여서 실행이 안 됨 ㅜㅜ 주의!

❗export할 때도 주의해야한다!
그냥 복붙했더니 해당 state를 보내지 않아서 실행이 되지 않음.. 사용할state.actions!!

2. +버튼 클릭 시 addCount

(Cart.js)

import { addCount } from './../store.js'
import { useDispatch } from 'react-redux'

<div>
  let dispatch = useDispatch();

  <tbody>
    {
      state.cart.map((a, i)=>
        <tr key={i}>
          <td>{state.cart[i].id}</td>
          <td>{state.cart[i].name}</td>
          <td>{state.cart[i].count}</td>
          <td>
            <button onClick={()=>{ dispatch(addCount(i)) }}>+</button>
          </td>
        </tr>
       )
     }
  </tbody> 
</div>

addCount(0)을 하면 0번재 상품이 +1되고
addCount(1)을 하면 1번재 상품이 +1됨

그런데 지금 반복문(map)을 사용하고 있으니
+버튼을 누르면 addCount(i)로 해주면
0번째 버튼 클릭 시 addCount(0) 실행해주고,
1번째 버튼 클릭 시 addCount(1) 실행해줌

❗ dispatch
import도 꼭 해주어야 함!
그리고 dispatch도 꼭 써줘야 실행 됨

✔️ 근데 이렇게만 해주고 끝내면 생길 수 있는 버그가 있음.

만약 정렬버튼이 있다고 생각해보자.
정렬버튼을 클릭해서 장바구니의 상품 순서가 뒤바뀐다고 하면
수량 변경하고싶은 상품의 수량이 제대로 변경되지 않을 수 있음.

이런 오류를 잡으려면

  • 버튼 클릭 시 버튼 옆 상품id(#)를 들고와 이것과 같은 id를 가진 상품의 count(수량)을 +1

해달라고 코드를 짜면 됨.

그래야 나중에 삼품 순서가 바뀌어도 잘 동작함.



🤔 수량 +1 기능 더 정확하게 만들기

1. 상품 id 전송

dispatch(addCount(state.cart[i].id)) 

그래서 버튼 클릭 시 옆에 있는 상품 id를 payload로 전송하라고 코드 짯음

2. payload로 보낸 id값과 같은 id를 가진 상품을 찾아 +1

let cart = createSlice({
  name : 'cart',
  initialState : [
    {id : 0, name : 'White and Black', count : 2},
    {id : 2, name : 'Grey Yordan', count : 1}
  ],
  reducers : {
    addCount(state, action){
      let 번호 = state.findIndex((a)=>{ return a.id === action.payload })
      state[번호].count++
    }
  }
}) 

array 자료에서 원하는 항목을 찾으려면
반복문, find(), findIndex()같은걸 쓰면 됨.

findeIndex()는 array뒤에 붙일 수 있는데

  • 안에 콜백함수를 넣고 return뒤에 조건식 추가
  • a라는 파라미터는 array안에 있는 자료를 뜻 함
  • array안에 있던 자료를 다 꺼내 조건식에 대입해보는데 조건식이 참이면 그게 몇번재 자료인지를 return함

그래서 위 코드는 a.id와 payload가 같으면 그게 몇 번째 자료인지 변수에 저장하라는 소리임

그걸 state뒤 바인딩해서 인덱싱해주면 끝~




🤔 주문버튼 클릭 시 state에 새로운 상품 추가

상세페이지(detail/id)의 주문하기 버튼 클릭 시
장바구니 state 항목에 주문하기 버튼을 누른 상품이 추가되었으면 한다.

이것도 위에서 한 수량문제처럼
state변경함수를 만들고 exprot import해서 만들어보겠음

1. state 변경함수 생성

let cart = createSlice({
  name : 'cart',
  initialState : [
    {id : 0, name : 'White and Black', count : 2},
    {id : 2, name : 'Grey Yordan', count : 1}
  ],
  reducers : {
    addCount(state, action){
      state[action.payload].count++
    },
    addItem(state, action){
      state.push(action.payload)
    }
  }
}) 

addItem이라는 state변경함수를 만들어봤다.

addItem( {id : 2, name : 'Red Knit', count : 1} ) 해주면

{id : 2, name : 'Red Knit', count : 1}가 state에 추가된다.

exprot 후 가져다 쓰면 됨
export let { addItem } = cart.actions

2. addItem 실행 코드

(Detail.js)

<div className="col-md-6">
  <h4 className="pt-5">{찾은상품.title}</h4>
  <p>{찾은상품.content}</p>
  <p>{찾은상품.price}</p>
  <button className="btn btn-danger" onClick={()=>{
    dispatch(addItem( {id : 1, name : 'Red Knit', count : 1} ))
  }}>주문하기</button>
  </div>
</div> 

상세페이지에서 주문버튼 누르면 addItem() 이거 실행해달라고 코드짰슴.
(상단 import는 필수!)

그럼 이제 버튼 누를 때 {id : 1, name : 'Red Knit', count : 1} 이런 상품이 추가되는데

각각 다른 상세페이지여도 잘 동작하려면
'Red Knit' 라고 하드코딩하는게 아니라 현재 페이지의 상품명을 집어넣어야함

📎 응용문제
응용1. 표의 행마다 삭제버튼 만들고 그거 누르면 상품이 삭제되게 만들려면?
응용2. 주문하기 버튼 누를 때 이미 상품이 state안에 있으면 추가가 아니라 기존 항목 수량증가만?

profile
FrontEnd Developer with Vue.js, TypeScript

0개의 댓글