이전에 알아보았듯이, store에는 하나의 reducer만 등록이 되어있어야 한다. 그래서 여러 개의 reducer를 하나의 store에 등록하고 싶을 때는 여러 개의 reducer를 하나의 rootReducer에 등록을 해서 사용해야 한다.
이 때 하나의 rootReducer에 합칠 때 사용하는 것이 combineReducers()이다.
interface Action {
type: string;
}
const counter = (state = 0, action: Action) => {
switch (action.type) {
case "INCREMENT":
return state + 1;
case "DECREMENT":
return state - 1;
default:
return state;
}
}
export default counter;
이전에 counter앱에 사용했던 reducer이다. 두번째 인자에 action의 type을 interface를 이용해서 지정해줄 수 있다. 두번째 인자의 property중 type이라는 property의 datatype은 string이라는 뜻이다.
enum ActionType {
ADD_TODO = "ADD_TODO",
DELETE_TODO = "DELETE TODO"
}
interface Action {
type: ActionType;
text: string;
}
const todos = (state = [], action: Action) => {
switch (action.type) {
case 'ADD_TODO' :
return [...state, action.text];
default :
return state;
}
}
export default todos;
todo list에 사용될 state를 관리하는 reducer 함수이다. 열거형(enum)의 맴버로 두가지 string을 선언하고 action의 type property의 값이 맴버이어야만 한다고 정의하고 있다.
import { combineReducers } from "redux";
import counter from "./counter"
import todos from "./todos"
const rootReducer = combineReducers({
counter,
todos
})
export default rootReducer;
combineReducers()를 이용해서 rootReducer에 2개의 reducer를 등록한다.
/index.tsx에 다음과 같은 추가해서 실행한 결과
const store = createStore(rootReducer);
store.dispatch({
type: "ADD_TODO",
text: "USE REDUX"
});
console.log('store.getState', store.getState());
getState()의 반환값으로 두 reducer의 두 개의 state의 값이 object의 property로 묶여서 전달되는 것을 알 수 있다.
그리고 각 property명은 누가 정해주지 않았는데 자동으로 reducer 함수명으로 지정되었다.