[컴][자바스크립트] 간단한 Redux 사용 설명



Redux 이해

아래 2개의 글 정도면 대략적인 이해가 가능할 듯 하다.




Redux 사용

  1. Store 만들기 : store 를 만들고
    var store = Redux.createStore(...)
  2. reducer 등록 : 이 store 의 state 를 변경하는데 사용되는 함수(reducer 라고 부른다.) 를 인자로 넘겨준다.
    var store = Redux.createStore(counter)  // counter is function
  3. listener 등록 : 그리고 이 state 가 변경될 때 마다 호출되는 함수인 listener 를 listener 에 등록을 한다. subscribe 을 이용하면 된다.
    store.subscribe(render) // render is function 
  4. dispatch(event 발생)
    1. reducer : store 에서 dispatch 를 실행하면 위에서 등록한 reducer 를 실행하게 된다.
      store.dispatch({ type: 'INCREMENT' })
    2. listener : reducer 의 실행이 끝나면 등록된 listener 들을 실행시킨다.
      for (var i = 0; i < listeners.length; i++) {
            listeners[i]();
      }


combineReducers()[ref. 3]

이녀석은 여러 reducer, 즉 state tree 가 여러개 여서, reducer 가 여러개 인 경우에 사용하기 위한 녀석이다.

이녀석에 대해 이야기 하기 전에 미리 알아야 할 점은 Redux code 의 store.dispatch 부분이다.

이 dispatch 에서는 단 한개의 reducer(currentReducer) 만을 호출한다. 그러므로 만약 우리가 여러개의 state tree 를 가지고 있어서 여러개의 reducer 를 호출해야 한다면, redux 를 사용할 수 없다.

그래서 Redux 에서는 이런 경우에 여러 "특정 state tree" 에 대해 "특정 state reducer" 를 호출해주는 함수를 등록해서 사용하도록 하고 있다.

그래서 Redux 에서는 combineReducers 라는 helper 함수를 제공한다. 

이녀석은 아래처럼 사용한다.
combineReducers({ todos: myTodosReducer, 
                  counter: myCounterReducer })

좀 더 긴 code 를 봐보자.
let previousState = {
   counter: 'SHOW_ALL',
   todos: [ 
     {
       text: 'Read the docs.',
       complete: false
     }
   ]
 }
let action = {type : "ACTION_ADD_TODO"}

let topReducer = combineReducers({ todos: myTodosReducer, 
                  counter: myCounterReducer })
var store = Redux.createStore(topReducer )

let nextState = store.dispatch(previousState, action)


위의 code 같은 경우라면 combinReducers 내부는 아래처럼 동작할 것이다.(실제 code 는 다르지만, 아래와 같은 결과를 가져다 준다.)
return{
  todos : myTodosReducer(state.todos, action)
  counter : myCounterReducer (state.counter, action)
}


이건 간단하게 생각하면, store (reducer 를 하나만 호출하는)에 reducer 를 등록하는 방법이라고 생각하면 된다. event 가 발생할 때마다, 해당하는 모든reducer 를 불러줘야 하는데, reducer 를 하나만 호출하도록 Redux 가 구성되어 있어서, 추가적으로 state 에 따라 reducer 를 분배할 수 있도록 combineReducer 를 만든 것이라고 생각하면 된다.

이 경우에 주의할 점은 reducer 에서 당연히 자신들이 다룰 수 있는 state 외의 값이 올 때에 대한 처리도 해놔야 한다.



Redux source flow

아래 소스를 직접 실행해 보고 싶다면 ref. 2 를 참고하자.

//reducer
function counter(state, action) {
    if (typeof state === 'undefined') {
      return 0
    }

    switch (action.type) {
      case 'INCREMENT':
        return state + 1
      case 'DECREMENT':
        return state - 1
      default:
        return state
    }
}

function render() {
    valueEl.innerHTML = store.getState().toString()
}


var store = Redux.createStore(counter)

function createStore(reducer, preloadedState, enhancer) {
    var _ref2;

    ...

    var currentReducer = reducer;
    var currentState = preloadedState;

    var currentListeners = [];
    var nextListeners = currentListeners;
    var isDispatching = false;

    ...

    dispatch({ type: ActionTypes.INIT });

    return _ref2 = {
        dispatch: dispatch,
        subscribe: subscribe,
        getState: getState,
        replaceReducer: replaceReducer
      }, _ref2[_symbolObservable2['default']] = observable, _ref2;


// subscribe
store.subscribe(render);
function subscribe(listener) {
    ...

    var isSubscribed = true;

    ensureCanMutateNextListeners();
    nextListeners.push(listener);

    // How to unsubscribe
    // var unsubscribe = store.subscribe(render);
    // unsubscribe()
    return function unsubscribe() {
      if (!isSubscribed) {
        return;
      }

      isSubscribed = false;

      ensureCanMutateNextListeners();
      var index = nextListeners.indexOf(listener);
      nextListeners.splice(index, 1);
    };
}

// dispatch event
store.dispatch({ type: 'INCREMENT' })
function dispatch(action) {
    ...

    try {
      isDispatching = true;
      currentState = currentReducer(currentState, action);
    } finally {
      isDispatching = false;
    }

    var listeners = currentListeners = nextListeners;
    for (var i = 0; i < listeners.length; i++) {
      listeners[i]();
    }

    return action;
}




react-redux 사용





See Also

  1. 쿠...sal: [컴][웹] Flux 예제 따라하기
  2. Example: Todo List · Redux



Reference

  1. Examples · Redux
  2. redux/src at master · reactjs/redux : redux sources
  3. Data Flow · Redux

댓글 없음:

댓글 쓰기