조건
상세페이지에서 버튼을 누르면 장바구니페이지에 해당 상품이 업데이트된다.
풀이
store.js
import { createSlice } from '@reduxjs/toolkit'
let cart = createSlice({
name : 'cart',
initialState : [
{id : 0, name : 'White and Black', count : 2},
{id : 1, name : 'Red Knit', count : 1}
] ,
reducers : {
...
addCart(state, action){
const newCart = action.payload;
return [...state, newCart];
}
}
})
export let { changeName, changeCount, addCart } = cart.actions
export default cart
Detail.js (상세페이지)
import { useDispatch, useSelector } from 'react-redux';
import { addCart } from './../store/cartSlice.js';
...
function Detail(props){
let dispatch = useDispatch()
...
return (
<div className={`container`}>
...
<h4 className="pt-5">{selectedShoes.title}</h4>
<p>{selectedShoes.content}</p>
<button className="btn btn-danger" onClick={()=>{ dispatch(addCart({ id, name : selectedShoes.title, count: 1 })); }}>장바구니</button>
</div>
...
</div>
)
Cart.js (장바구니)
import { useDispatch, useSelector } from 'react-redux';
...
function Cart(){
let state = useSelector((state)=> state);
const cartItems = useSelector(state => state.cart);
let dispatch = useDispatch()
return (
<div>
<h6>{ state.user }의 장바구니</h6>
<button onClick={()=>{ dispatch(changeUser()) }}>유저변경</button>
<Table>
<thead>
<tr>
<th>#</th>
<th>상품명</th>
<th>신상품변경</th>
<th>수량</th>
<th>수량변경</th>
</tr>
</thead>
<tbody>
{
cartItems.map((item, index) =>
<tr key={index}>
<td>{item.id}</td>
<td>{item.name}</td>
<td>
<button onClick={() => { dispatch(changeName(item.id)) }}>🔘</button>
</td>
<td>{item.count}</td>
<td>
<button onClick={() => { dispatch(changeCount(item.id)) }}>➕</button>
</td>
</tr>
)
}
</tbody>
</Table>
</div>
)
}
export default Cart;
알게 된 점
1. createSlice에서 생성된 리듀서 함수는 직접적인 상태 변이(mutations)를 허용하지 않는 Redux의 원칙을 따라야 한다. 따라서 state.push()와 같이 기존 배열을 직접 수정하는 방식은 Redux의 권장 사항에 어긋난다.
state 배열을 변경하지 않고, 새로운 배열을 생성하여 상태를 업데이트 해야 한다. 이를 위해 createSlice에서 제공하는 immer를 사용하면 된다.
2. 상세페이지 장바구니 버튼에서 dispatch(addCart(selectedShoes))로 쓰면 장바구니페이지에 빈칸으로 추가되는 오류가 난다. dispatch(addCart({ id, name : selectedShoes.title, count: 1 }))처럼 새로운 객체를 생성해서 전달해야 오류가 나지 않는다.
이 이유는 1번과도 연결되는데, selectedShoes를 그대로 전달하게 되면 기존 장바구니 배열에 참조로 추가되어 공유되므로 나중에 해당 객체가 변경되면 장바구니의 해당 아이템도 변경되므로 Redux의 원칙에 어긋나기 때문이다.
출처 : 코딩애플 https://codingapple.com/
'⚛️ React > 문제풀기 (코딩애플: React)' 카테고리의 다른 글
React : 최근 본 상품 만들기 (localStorage, map, JSON) (0) | 2023.07.03 |
---|---|
React : 장바구니 제품 수량변경 (map, redux, action, payload) (0) | 2023.06.22 |
React : 탭 내용 fade되도록 만들기 (+class에 변수 넣기) (0) | 2023.06.15 |
React : 탭 만들기 (if else, array로 만들기) + props 귀찮을 때 팁 (0) | 2023.06.12 |
React : 더보기 버튼을 누를 때마다 다른 get주소 데이터 불러오기 (+로딩중) (0) | 2023.06.01 |