store에 저장된 state가 array, object 자료인 경우
state 변경을 좀 쉽게 편리하게 할 수 있음
Immer.js 라이브러리가 Redux 설치하면 딸려서 설치됨
이 라이브러리가, 오브젝트의 값을 직접 변경해도 state 사본을 하나 더 생성해줌.
즉 아래코드처럼 직접수정해도 잘 반영됨
let user = createSlice({
name : 'user',
initialState : {name : 'kim', age : 20},
reducers : {
changeName(state){
state.name = 'park'
}
}
})
수정이 잦은 문자나 숫자부분은 그냥 오브젝트로 만드는게 더 편할듯.
왜요?
Immer.js는 state의 불변성을 유지하면서도 직접 수정하는 것처럼 코드를 작성할 수 있게 해줌.
내부적으로는 state의 draft 사본을 만들어서 그걸 직접 수정하듯 작성하게 하고, 수정이 끝나면 불변성을 유지한 새 객체로 바꿔줌.
그래서 직접 수정해도 되는 것처럼 보임.
return은 새 객체로 갈아치우는 방식.
즉 return을 쓸거면
changeName(state) {
return { name: 'park', age: 20 }; // 완전히 새로운 객체를 명시적으로 리턴
}
이렇게 해야함
둘이 같이 섞어쓰면 에러발생. 둘 중 한 방식만 쓰자.
수정함수에 값을 담아보낸다.
이후 함수에서 그 값을 가지고 놀 수 있다.
//cart.jsx
<Button onClick={()=>increase(2)}>나이 수정</Button>
//store.jsx
let user = createSlice({
name : 'user',
initialState : {name : 'kim', age : 20},
reducers : {
increase(state, action){
state.age += action.payload
}
}
})
payload : 대충 실어나른다는 뜻으로 만든거같음
action.type 하면 state변경함수 이름이 나오고
action.payload 하면 파라미터가 나옴
각 배열의 오브젝트에 접근필요. id값 활용하면 될듯
//store.jsx
//map 반복문을 통해 action.payload로 받아온 id값과 일치하는 item을 찾음. 있다면 아이템을 copy, count+1
userCartCountIncrement(state, action) {
return state.map((item) =>
item.id === action.payload ? { ...item, count: item.count + 1 } : item
);
},
userCartCountDecrement(state, action) {
return state.map((item) =>
item.id === action.payload ? { ...item, count: item.count - 1 } : item
);
},
//cart.jsx
{userCart.map(function (a, i) {
return (
<tr>
<td>{a.id}</td>
<td>{a.name}</td>
<td>{a.count}</td>
<td>
<Button
onClick={() => dispatch(userCartCountIncrement(a.id))}
>
+
</Button>
수량변경
<Button
onClick={() => dispatch(userCartCountDecrement(a.id))}
>
-
</Button>
</td>
</tr>
);
})}
userCart state 를 store.jsx에서 가져온 뒤 주문하기 버튼을 클릭하면 새로운 오브젝트를 추가하는 방식으로 하면 될듯.
수정함수에서 기존 state복사, 스프레드 함수를 활용하여 맨 뒤에 넣어놓으면 될듯.
//기존 배열에 오브젝트 추가 함수
addUserCart(state, action) {
//해당 아이디를 가지고있는 오브젝트가 있는지 체크
const existingItem = state.find((item) => item.id === action.payload.id);
//있다면 그거 카운트만 하나 증가
if (existingItem) {
return state.map((item) =>
item.id === action.payload.id
? { ...item, count: item.count + 1 }
: item
);
} else {
//없다면, 새 오브젝트 추가.
return [...state, { ...action.payload, count: 1 }];
}
},
copilot이 사실상 80프로 이상 했음...
모르는거 깔짝 찾아보다가 답답해서 ai 쓰는거 그만해야 할거같다.
실력이 늘지를 않음.