27
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Reduxをソースコードから理解する その1

Last updated at Posted at 2017-02-22

Reduxは簡単に全部読める規模のライブラリです。ソースコードを読んでからリファレンスを見たほうが理解しやすかったので紹介します。また、有名なコードを読むことによるJavaScriptの勉強も兼ねています。
今回はReduxの中心であるStoreの作成・初期化とdispatch()について見ていきます。

対象読者

Reduxを少なくとも1回くらい使ってみた人向けです。
バージョンは、2017-2-22時点でmasterの3f319eb7を見ています。

Store

Reduxはreactなどのview libraryと併用し、状態管理をするライブラリです。アプリの状態を1つにまとめた構造(=Store)に対して、操作(=Action)を割り当てる(Dispatch)することで遷移させます。

Store · Redux
まずは、Storeを作成するcreateStore()をみていきます。しばらくreducer以外の引数はundefinedだと思っておきます。そうして、関数定義とエラーチェックを省略すると、実体はこれだけです。dispatch({ type: ActionTypes.INIT })が気になります。

createStore.js
export default function createStore(reducer, preloadedState, enhancer) {

エラーチェック

  let currentReducer = reducer
  let currentState = preloadedState
  let currentListeners = []
  let nextListeners = currentListeners
  let isDispatching = false

関数定義

  dispatch({ type: ActionTypes.INIT })

  return {
    dispatch,
    subscribe,
    getState,
    replaceReducer,
    [$$observable]: observable
  }
}

dispatch()は3つのことを行います。currentState更新、currentListenersの更新、listener()の呼び出しです。
dispatch({ type: ActionTypes.INIT })を呼び出した時点では、listenersは空の配列です。つまり、currentState更新しかしません。このdispatch()によって、Stateの初期化を行います。

今考えている状態はcurrentState = preloadedState、つまりcurrentStateundefinedです。currentReducer()は、createStoreの引数で、ユーザが決めたreducerなのでした。

createStore.js
  function dispatch(action) {

エラーチェック

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

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

    return action
  }

Reducers

Reducers · Redux
ReducersはRedux利用者が定義する関数で、Storeのdispatch()currentReducer()として呼び出されます。
前述のStore初期化のために、渡されたStateがundefinedだった場合、初期値を返す必要があります。また、それ以外のときにActionTypes.INITのように自分で定義していないActionが渡された場合は、Stateを変更しないで返す必要があります。

createStore.js
/**
 * These are private action types reserved by Redux.
 * For any unknown actions, you must return the current state.
 * If the current state is undefined, you must return the initial state.
 * Do not reference these action types directly in your code.
 */
export const ActionTypes = {
  INIT: '@@redux/INIT'
}

サンプルコードなどでは、こんな感じで書いているものが多いようです。

Reducer
const reducer = (state = initialState, action) => {
  switch (action.type) {
    case UPDATE:
      // update state
      return newState;
    default:
      return state;
  }
};

あとがき

Reduxはいろんな機能を実装した便利なソフトウェアというわけではなくて、優れた考え方が支持されたソフトウェアなのだな、と思います。コメントも多いので、JavaScriptの勉強にも向いているのではないでしょうか。見切り発車で「その1」と銘打ってみたので、次回に続く予定です。

次回:Reduxをソースコードから理解する その2 - Qiita

27
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?