toggle counter button을 누르면
counter button이 사라지거나 보이게 한다.
이것은 redux로 관리하는 것보다는
useState로 관리하는 것이 낫다.
local state이기 때문이다.
즉, state는 지금 컴포넌트 에서만 사용할 것이다.
그런데 연습을 위해
Counter와 state 모두가
Counter가 보여야 할지말지를 정한다고 가정하자.
즉, global state임을 가정하자.
toggle 버튼을 클릭해서 액션을 디스패치 하고
리덕스에서 state를 변경한다.
그건 counter가 보이는 div태그를 보이게 할지 말지 제어한다.
리덕스 스토어에 새 정보를 추가하자.
counterReducer로 가서 모든 state 스냅샷을 추가한다.
initialState snapshot
const counterReducer = (state = { counter: 0, showCounter: true }, action) => {
가독성을 높이기 위해 initialState로 추출해서 할당한다.
const initialState = { counter: 0, showCounter: true };
const counterReducer = (state = initialState, action) => {
counterReducer function 변경
리덕스는 initial State에서 변화된 것을 합치치 않는다.
action.type에서 return된 객체로 기존의 것을 대체할 뿐이다.
그러므로 기존의 showCounter value를 넣을 함수인
showCounter: state.showCounter로 채워넣자.
increment 일 때는 showCounter를 변경하고 싶지 않기 때문이다.
마찬가지로 decrement와 increase 일 때도 해주자.
그리고 action.type을 toggle일 때도 추가해 준다.
const counterReducer = (state = initialState, action) => {
if (action.type === "increment") {
return {
counter: state.counter + 1,
showCounter: state.showCounter,
};
}
if (action.type === "decrement") {
return {
counter: state.counter - 1,
showCounter: state.showCounter,
};
}
if (action.type === "increase") {
return {
counter: state.counter + action.amount,
showCounter: state.showCounter,
};
}
if (action.type === "toggle") {
return {
showCounter: !state.showCounter,
counter: state.counter,
};
}
toggle일 때는 기존의 showCounter 상태와 반대여야 하므로 ! exclamation mark를 사용하고
counter는 기존의 상태를 유지해야 하므로 state.counter로 그대로 놓도록 한다.
이제 리덕스에서 toggle타입을 지원해 준다.
Counter컴포넌트에서 useSelector로 showCounter의 상태를 가져온다.
그리고 show가 truthy일 때만 counter div 태그를 보여준다.
const show = useSelector(state => state.showCounter);
...
{show && <div className={classes.value}>{counter}</div>}
하면 안되는 예시들
하면 안되는 예시
const counterReducer = (state = initialState, action) => {
if (action.type === "increment") {
state.counter++
return state
}
제대로 작동되는 것처럼 보이지만 잘못된 코드다.
리덕스로 작업할 때는 이렇게 하면 안된다.
*****중요 : 절대 기존의 state를 변형해서는 안 된다 *****
대신 새로운 state 객체를 반환하여 재정의 해야 한다.
객체와 배열은 자바스크립트에서 참조 값이기 때문에
뜻하지않게 기존의 state를 재정의하거나 변경하기 쉽다.
하면 안되는 예시 2
const counterReducer = (state = initialState, action) => {
if (action.type === "increment") {
state.counter++
return {
counter: state.counter,
showCounter: state.showCounter,
};
}
이미 return 이전에 state.counter를 더했기 때문에
그대로의 state.counter를 counter에 재정의 하면 될것만 같다.
그러나 이것도 좋지 않은 예시다.
객체 배열이
자바스크립트에서 참조값이기 때문에
여전히 기존의 state를 변형시키고 있는 코드다.
버그로 예측 불가능한 동작이 발생할 수 있고,
프로그램 디버깅도 어려워 질 수 있다.
'공부기록 > [강의노트] Udemy React 완벽가이드 201~300' 카테고리의 다른 글
# 255 [udemy React 완벽 가이드 노트] Redux toolkit에서 여러개의 reducer 사용해보기 (0) | 2022.10.14 |
---|---|
# 251 [udemy React 완벽 가이드 노트] Redux toolkit 사용해보기 (리덕스가 관리해야 할 state가 많아질 때 문제점과 개선 방안) (0) | 2022.10.14 |
# 248 [udemy React 완벽 가이드 노트] action에 페이로드(추가속성) 연결하기 (0) | 2022.10.12 |
# 247 [udemy React 완벽 가이드 노트] 클래스 기반 컴포넌트가 있는 리덕스 (0) | 2022.10.12 |
# 243 [udemy React 완벽 가이드 노트] 리액트용 리덕스 스토어 만들기 (0) | 2022.10.12 |