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
!!
(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도 꼭 써줘야 실행 됨
✔️ 근데 이렇게만 해주고 끝내면 생길 수 있는 버그가 있음.
만약 정렬버튼이 있다고 생각해보자.
정렬버튼을 클릭해서 장바구니의 상품 순서가 뒤바뀐다고 하면
수량 변경하고싶은 상품의 수량이 제대로 변경되지 않을 수 있음.
이런 오류를 잡으려면
해달라고 코드를 짜면 됨.
그래야 나중에 삼품 순서가 바뀌어도 잘 동작함.
dispatch(addCount(state.cart[i].id))
그래서 버튼 클릭 시 옆에 있는 상품 id를 payload로 전송하라고 코드 짯음
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뒤에 붙일 수 있는데
그래서 위 코드는 a.id와 payload가 같으면 그게 몇 번째 자료인지 변수에 저장하라는 소리임
그걸 state뒤 바인딩해서 인덱싱해주면 끝~
상세페이지(detail/id)의 주문하기 버튼 클릭 시
장바구니 state 항목에 주문하기 버튼을 누른 상품이 추가되었으면 한다.
이것도 위에서 한 수량문제처럼
state변경함수를 만들고 exprot import해서 만들어보겠음
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
(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안에 있으면 추가가 아니라 기존 항목 수량증가만?