Redux - 여러개의 state

 저번에 장난감가게를 비유로 간단한 Redux를 만들어 봤습니다. 이제 이 사장은 쿠기(cookie)를 팔려고 계획중입니다. 그래서 기존 직원을 교육시켜 쿠키도 팔수 있도록 훈련을 시켰습니다. 훈련이 완료된후 판매을 시작했습니다.





이 그림에서 보연 알다싶이 직원이 이제 2가지 행동(action)을 하는것을 알수 있습니다. 이 점을 기억하시고 코드를 살펴봐 주시기 바랍니다.


// 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'
};
};

저번에 1개의 function만 있었다면 이번에는 buyCookie가 추가됬습니다. 이 action은 고객이 쿠키를 살때 사용할 function입니다.


// 초기 state상태
const initialState = {
numOfToy: 10, // 초기에 장난감이 10개
numOfCookie : 15
}

당연히 초기상태에 이제 쿠키의 갯수(15개)가 state에 추가됬습니다. 이제 initialState에는 초기 장난감과 쿠기의 갯수가 각각 저장되어 있습니다.

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

case BUY_COOKIE: return { // 쿠키를 구매하는 action
...state, // 이전 단계의 state를 복사한다.
numOfCookie : state.numOfCookie -1 // numOfCookie만 이전 state에서 1 감소
};

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

이제 reducer에서도 case를 추가합니다. BUY_COOKIE case을 추가하여 고객이 쿠키를 구매할시 numOfCookie의 수량이 1 줄어들도록 합니다.


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

// 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()); // 실행이 안됨

이전코드와 다른점은 dispatch의 전달인자로 buyCookie()가 추가된 것입니다. buyToy()가 3번 실행되고 buyCookie()가 2번 실행된 것을 볼때 장난감은 3개, 쿠키는 2개 팔리는 것을 알수 있습니다.


물론 1개의 reducer로 얼마든지 state를 추가 할수 있습니다. 하지만 그렇게 되면 code의 복잡도가 높아지고 debug가 어려워 지게 됩니다. 그래서 다음은 직원(reducer)를 추가하는 방법에 대해서 알아보도록 하겠습니다.


이전글 : Redux - 개념정리(비유 및 코드)


다음글 : Redux - 여러명의 직원(reducer)


위 관련된 코드(아래)


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'
};
};


// Reducer
// (previousState, action) => newState

// 초기 state상태
const initialState = {
numOfToy: 10, // 초기에 장난감이 10개
numOfCookie : 15
}



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

case BUY_COOKIE: return { // 쿠키를 구매하는 action
...state, // 이전 단계의 state를 복사한다.
numOfCookie : state.numOfCookie -1 // numOfCookie만 이전 state에서 1 감소
};

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



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

// 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)