관리 대상 state가 복잡하거나 reducer 함수로 관리해야할 성격이 다른 경우 combine reducer를 이용할 수 있다.
여러 리듀서 함수를 하나의 rootReducer로 묶을 때 combineReducers를 이용한다.
서로 관련있는 상태 변경에 대한 로직을 각 함수로 분리하면서 관리가 수월해진다.
필요한 기능 꺼내오기
const { Provider, useSelector, useDispatch } = ReactRedux;
const { combineReducers, createStore } = Redux;
관리해야할 상태들을 설정
const countInitState = {
currentCount : 0
};
const activationInitState = {
isActivity : false
};
const userInitState = {
name : '',
email: '',
phone: ''
}
combineReducers
return 값은
key : state로된 객체 형태를 반환
const rootReducer = combineReducers({
countReducer : (state = countInitState, action) => {
const { type, payload } = action;
switch(type) {
case 'INCREMENT' :
return {
currentCount : state.currentCount + payload.incrementValue
};
case 'DECREMENT' :
return {
currentCount : state.currentCount - payload.decrementValue
};
default :
return state;
}
},
activationReducer : (state = activationInitState, action) => {
const { type } = action;
switch(type) {
case 'TOGGLE' :
return {
isActivity : !state.isActivity
};
default :
return state;
}
},
userReducer : (state = userInitState, action) => {
const { type, payload } = action;
switch(type) {
case 'INPUT' :
return {
...state,
[payload.name] : payload.value
};
default :
return state;
}
}
});
store 생성 시 reducer는 하나만 사용할 수 있기 때문에 combineReducers를 이용한 rootReducer를 전달한다.
const store = createStore(rootReducer);
크롬 확장 프로그램 redux devtool설치 후 적용하기 위해 작성
const store = createStore(
rootReducer,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
combineReducers를 이용하는 경우 useSelector의 콜백 함수의 매개변수로 rootReducer의 state가 전달된다.
해당 state에서 reducer 설정한 key 값을 통해 사용하고자하는 state 값만 가져올 수 있다.
const { currentCount } = useSelector(state => state.countReducer);
const { isActivity } = useSelector(state => state.activationReducer);
const { name, email, phone } = useSelector(state => state.userReducer);
const dispatch = useDispatch();
const incrementCount = () => {
dispatch({
type : 'INCREMENT',
payload : {
incrementValue : 1
}
});
};
const decrementCount = () => {
dispatch({
type : 'DECREMENT',
payload : {
decrementValue : 1
}
});
};
const toggleActivation = () => {
dispatch({
type : 'TOGGLE'});
};
const onChangeHandler = (e) => {
dispatch({
type : 'INPUT',
payload : {
name : e.target.name,
value : e.target.value
}
});
};