Redux store에 저장된 state가 array,object 자료인 경우,
state 변경을 좀 편리하게 할 수 있다
그 방법을 알아보자
redux state가 array/object인 경우 변경하려면
let user = createSlice({
name : 'user',
initialState : {name : 'kim', age : 20},
reducers : {
changeName(state){
state.name = 'park'
}
}
직접 state를 수정해도 변경이 잘 됩니다
array/object 자료의 경우 state변경은
state를 직접 수정해버려도 잘 되니까 직접 수정하십시오.
만약,버튼을 눌렀을때 변경하려는 자료의 +1을 해주고 싶으면?
let user = createSlice({
name : 'user',
initialState : {name : 'kim', age : 20},
reducers : {
increase(state){
state.age += 1
}
}
})
export let {increase} = user.actions
이렇게 increase 라는 함수를 만들고, export해서 쓰면 됩니다
다른 페이지의 버튼 누르는 곳에서 import 해서 dispatch(increase()) 하면, +1이 됩니다
state 변경함수가 여러개 필요하다면?
방금 위에서 +1하는 기능을 만들어봤는데
가끔은 +10도 , +100도 하고 싶겟죠?
굳이 state 변경함수를 여러개 만들지 않아도 파라미터 문법을 이용하면
이모든게 함수 한개로도 가능합니다.
let user = createSlice({
name : 'user',
initialState : {name : 'kim', age : 20},
reducers : {
increase(state, action){
state.age += action.payload
}
}
})
store에는 이렇게 변경함수 increase를 저장해두고,
필요한 곳에 가서 dispatch(increase(10))또는 dispatch(increase(100)) 이런식으로 써주면 됩니다.
참고로, action.payload는 state변경함수 안의 파라미터를 그대로 받아오는 역할을 합니다.
즉 여기서는 state.age += 10, state.age += 100 이런식으로 적용된 것이죠
문제 1. + 버튼을 누르면 해당 상품의 수량부분이 +1 되는 기능을 만들어보자.
(Cart.js)
import { useDispatch, useSelector } from 'react-redux'
import {changeCount} from './store.js'
function Cart(){
let carts = useSelector((state)=>{return state.carts})
let dispatch = useDispatch() //store.js로 요청을 보내주는 함수임
return(
{
carts.map((item,i)=>{
return (
<tbody key={i}>
<tr>
<td>{carts[i].id}</td>
<td>{carts[i].name}</td>
<td>{carts[i].count}</td>
<td>
<button onClick={()=>{
dispatch((changeCount(i))
//+버튼을 눌렀을때 count가 1씩 증가함
}}>➕</button>
</td>
</tr>
</tbody>
)
})
}
)}
만약 changeCount()안에 i를 전달한다면? ~~번째로 전달하는 것
만약 changeCount()안에 id를 전달한다면? 고유의 id로 전달하는 것
(store.js)
let carts = createSlice({
name: 'carts',
initialState:
[
{id : 0, name : 'Red Knit', count : 2},
{id : 2, name : 'Grey Yordan', count : 1},
{id : 3, name : 'Rockey', count : 1}
],
// 변경함수 파라미터에 넣은 자료들은 action.payload하면 자료가 나옴
reducers:{
changeCount(state,action){
state[action.payload].count += 1
}
}
})
export let {changeCount, addItem} = carts.actions
action.payload로 i를 데려와서, state의 i번째 item의 count를 직접 변경해준다
단. state가 배열인지, 객체인지를 잘 구별해야함
왜냐하면 배열인 경우 바로 count를 붙여버리면 error 나기 때문
배열은 먼저 index 로 item을 찾아주고, 그 객체에서 키를 뽑는 순서로 가야댐
지금까지는 배열의 순서, 즉 i를 파라미터로 하여 state를 변경해보았다.
이번에는 고유의 id 값을 파라미터로 하여 변경해보겟다.
굳이 왜 이렇게 하나면
만약, 가나다순, 낮은가격순정렬 등의 버튼으로 인한 배열이 흐트러질 문제가 생길수도 있다.
그러니, id를 파라미터로 해서 변경하는 것이 확실하당
{
carts.map((item,i)=>{
return (
<tbody key={i}>
<tr>
<td>{carts[i].id}</td>
<td>{carts[i].name}</td>
<td>{carts[i].count}</td>
<td>
{/* 특정 id의 +버튼을 누르면 동일 id의 상품 수량이 +1이 되도록 */}
{/* id를 사용하는 이유: 만약 정렬버튼을 눌렀을때 0번째 +버튼을 눌렀는데 기존에 2번째였던 상품갯수가 +1이 될수있는 사태방지 */}
<button onClick={()=>{
dispatch((changeCount(carts[i].id)))
}}>➕</button>
</td>
</tr>
</tbody>
)
})
}
()안에 id를 넣어주고, dispatch로 옮겨주엇다
let carts = createSlice({
name: 'carts',
initialState:
[
{id : 0, name : 'Red Knit', count : 2},
{id : 2, name : 'Grey Yordan', count : 1},
{id : 3, name : 'Rockey', count : 1}
],
reducers:{
changeCount(state,action){
//action.payload와 state의 id가 같은 인덱스만 찾는다
let idIndex = state.findIndex((item)=>{return item.id === action.payload})
state[idIndex].count += 1
}
}
})
export let {changeCount} = carts.actions
변경함수 파라미터에 넣은 자료들은 action.payload하면 자료가 나옴
dispatch((changeCount(파라미터)))
state의 배열에서 item의 id 와 입력된 파라미터 값이 동일한 인덱스를 찾는다. (findIndex)
그다음, state에서 위에서 찾은 인덱스 번째의 count를 +1 해준다
문제 2. 상세페이지 주문하기 버튼을 누르면 새로운 상품이 state에 추가되는 기능을 만들어옵시다.
let carts = createSlice({
name: 'carts',
initialState:
[
{id : 0, name : 'Red Knit', count : 2},
{id : 2, name : 'Grey Yordan', count : 1},
{id : 3, name : 'Rockey', count : 1}
],
reducers:{
changeCount(state,action){
let idIndex = state.findIndex((item)=>{return item.id === action.payload})
state[idIndex].count += 1
},
addItem(state,action){
state.push(action.payload)
}
}
})
export let {changeCount, addItem} = carts.actions
reducers 안에 addItem 이라는 새로운 함수를 만들어두고,
state.push(action.payload)로 state에 새로 들어온 데이터를 추가해줍니다
그다음 state 변경함수를 export 하고,
적용할 페이지에서 import 해준다음
<button onClick={()=>{dispatch(addItem({id : 1, name : 'White and Black', count : 1}))}}
className="btn btn-danger">주문하기</button>
addItem ()안에 새롭게 추가될 데이터를 객체 형태로 넣어주면 됩니당!~
주문하기 버튼을 누르면
카트 페이지에서 상품이 담기는 것을 확인할 수 있어요~
'React' 카테고리의 다른 글
localStorage로 만드는 최근 본 상품 저장하기 (0) | 2023.04.16 |
---|---|
Redux-toolkit : 장바구니 기능 관련 응용문제 (0) | 2023.04.13 |
Redux-toolkit : store의 state 변경하는 법 (2) | 2023.04.09 |
Redux-toolkit : store에 state 보관하고 쓰는 법 (0) | 2023.04.08 |
(transition)컴포넌트 전환 애니메이션 만들기 (0) | 2023.04.08 |