Redux - 여러명의 직원(reducer)

 이제 새로운 직원을 뽑아서 전담하여 쿠키만 판매할려고 합니다. 그러기 위해서 새로운 직원(reducer)을 뽑아야 겠죠. 






// Action
const BUY_TOY = 'BUY_TOY'; // type을 설정한다(문자열)
const BUY_COOKIE = 'BUY_COOKIE'; // type을 설정한다(문자열)
function buyToy(){ // 고객이 장난감을 살때
return {
type: BUY_TOY,
info: 'First step of redux action'
};
};

function buyCookie(){ // 고객이 쿠키를 살때
return {
type: BUY_COOKIE,
info: 'First step of redux action'
};
};

고객의 action은 장난감 또는 쿠키를 구매하는 것이기 때문에 이전 코드와 동일하게 작성합니다.


// 초기 state상태(2개의 initial state)
const initialToyState = {
numOfToy: 10, // 초기에 장난감이 10개
}

const initialCookieState = {
numOfCookie : 15, // 초기에 쿠키는 15개
}

이제 이전 글에서는 1개의 initialState를 사용했지만 이번에는 분할하여 각각 initialToyState, initialCookieState로 나누어 줍니다.


// 장난감 전담 직원(toyReducer)
const toyReducer = (state = initialToyState, action) => {
switch(action.type){ // action의 타입을 확인하여 case를 실행
case BUY_TOY: return { // 장난감을 구매하는 action
...state, // 이전 단계의 state를 복사한다.
numOfToy : state.numOfToy -1 // numOfToy만 이전 state에서 1 감소
};

default : return state; // 어느 case에도 속하지 않으면 그대로 state 출력
}
};

// 쿠키 전담 직원(cookieReducer)
const cookieReducer = (state = initialCookieState, action) => {
switch(action.type){ // action의 타입을 확인하여 case를 실행
case BUY_COOKIE: return { // 쿠키를 구매하는 action
...state, // 이전 단계의 state를 복사한다.
numOfCookie : state.numOfCookie -1 // numOfCookie만 이전 state에서 1 감소
};

default : return state; // 어느 case에도 속하지 않으면 그대로 state 출력
}
}

이제 각각의 장난감, 쿠키 판매 직원의 행동(action.type)을 지정해 줍니다. 여기서는 각각의 수량이 1줄어드는 것입니다. 


// 1. app의 state를 갖고 있는다. (인자로 reducer)
// createStore를 이용하여 storage를 생성
const storage = createStore(reducer);

그런데 문제가 있습니다. reducer는 하나의 app에 하나만 존재가 가능하다고 제가 말했습니다. 그러면 현재 1개의 reducer를 인자로 해서 storage를 생성해야 하는데 현재상황에서는 불가능 합니다. 

 따라서 각각의 toyReducer, cookieReducer를 합치는 작업을 해야 합니다. (직원을 합친다고 하면 이상하니 그냥 reducer를 합치는 것으로 하겠습니다.)


const redux = require('redux')
const createStore = redux.createStore;
const combineReducer = redux.combineReducers; // 여러개의 reducer를 합치기 위한 method

일단 redux.combineReducers를 이용해야 합니다. 이는 여러개의 reducer를 하나로 사용할수 있게 하는 method입니다. 가장 위쪽에 combineReducer를 추가해 줍니다.


// 합쳐진 reducer 변수
const rootReducer = combineReducer({
toy : toyReducer,
cookie : cookieReducer
})

이제 각각의 reducer를 합칩니다. 맨 위쪽에서 만든 combineReducer를 이용하여 키값을 각각 toy, cookie로 합니다. 그리고 value는 각각 해당되는 reducer로 합니다.


// 1. app의 state를 갖고 있는다. (인자로 reducer)
// createStore를 이용하여 storage를 생성
// 다른 reducer가 합쳐진 rootReducer를 인자로 갖습니다.
const storage = createStore(rootReducer);

이제 rootReducer를 인자로 갖는 storage를 생성하고 'node index'를 실행해 봅니다.



이전글의 출력된 console.log와 조금 다른것을 알수 있습니다. 이제 장난감의 갯수에 접근할려면 'state.toy.numOfToy'로 접근을 해야 합니다. 바깥쪽에 {}가 생겨 한번 더 거쳐야 한다는 것을 알게 됬죠. 


그리고 둘중 어느 reducer가 action을 하든 toy,cookie가 반응을 합니다. 다만 관련 있는것은 state가 적용이 되고 관련 없는 것은 무시를 하게 됩니다.


이전글 : Redux - 여러개의 state

다음글 : Redux - Middleware(미들웨어)


위 자료에 사용한 전체 코드(아래쪽)


const redux = require('redux')
const createStore = redux.createStore;
const combineReducer = redux.combineReducers; // 여러개의 reducer를 합치기 위한 method


// Action
const BUY_TOY = 'BUY_TOY'; // type을 설정한다(문자열)
const BUY_COOKIE = 'BUY_COOKIE'; // type을 설정한다(문자열)
function buyToy(){ // 고객이 장난감을 살때
return {
type: BUY_TOY,
info: 'First step of redux action'
};
};

function buyCookie(){ // 고객이 쿠키를 살때
return {
type: BUY_COOKIE,
info: 'First step of redux action'
};
};


// 초기 state상태(2개의 initial state)
const initialToyState = {
numOfToy: 10, // 초기에 장난감이 10개
}

const initialCookieState = {
numOfCookie : 15, // 초기에 쿠키는 15개
}

// 장난감 전담 직원(toyReducer)
const toyReducer = (state = initialToyState, action) => {
switch(action.type){ // action의 타입을 확인하여 case를 실행
case BUY_TOY: return { // 장난감을 구매하는 action
...state, // 이전 단계의 state를 복사한다.
numOfToy : state.numOfToy -1 // numOfToy만 이전 state에서 1 감소
};

default : return state; // 어느 case에도 속하지 않으면 그대로 state 출력
}
};

// 쿠키 전담 직원(cookieReducer)
const cookieReducer = (state = initialCookieState, action) => {
switch(action.type){ // action의 타입을 확인하여 case를 실행
case BUY_COOKIE: return { // 쿠키를 구매하는 action
...state, // 이전 단계의 state를 복사한다.
numOfCookie : state.numOfCookie -1 // numOfCookie만 이전 state에서 1 감소
};

default : return state; // 어느 case에도 속하지 않으면 그대로 state 출력
}
}

// 합쳐진 reducer 변수
const rootReducer = combineReducer({
toy : toyReducer,
cookie : cookieReducer
})

// 1. app의 state를 갖고 있는다. (인자로 reducer)
// createStore를 이용하여 storage를 생성
// 다른 reducer가 합쳐진 rootReducer를 인자로 갖습니다.
const storage = createStore(rootReducer);

// 2. method getState()를 통해서 state에 접근할수 있도록 한다.
console.log('초기상태', storage.getState());

// 4. method subscribe(listener)를 통해 listeners를 등록한다. (state가 변경시 app에 반영)
// state가 업데이트 될때마다 console.log에의해 업데이트 상태 storage.getState()에 의해 출력된다.
const unsubscribe = storage.subscribe(() => console.log('업데이트 상태', storage.getState()));


// 3. method dispatch(action)를 통해서 state를 updated할수 있도록 한다.
// dispatch을 통해 action을 취할때 reducer는 action.type가 BUY_TOY라는 것을 알수 있습니다.
storage.dispatch(buyToy());
storage.dispatch(buyToy());
storage.dispatch(buyToy());

storage.dispatch(buyCookie());
storage.dispatch(buyCookie());

// 5. 등록되지 않은 listeners 해제
unsubscribe();

storage.dispatch(buyToy()); // 실행이 안됨
storage.dispatch(buyCookie()); // 실행이 안됨




댓글

이 블로그의 인기 게시물

Lesson 12_1 프로퍼티 노드(Property Node)

DAQ로 전압 측정하기-2

Lesson 12_2 참조를 이용한 프로퍼티노드(Property Node)