1
1

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のcreateStore()の処理を追う(Middlewareを使わない場合)

Last updated at Posted at 2019-04-29

Node.js初心者がRedux勉強中です。よく分からなかったのでソースを読んでます。

createStore.jsのソース

最初に使うcreateStore()は、createStorejsにあります。
https://github.com/reduxjs/redux/blob/v4.0.1/src/createStore.js

createStore()は、Middlewareを使う場合と使わない場合で処理の流れが違っています。この記事では"Middlewareを使わない場合"の処理を追っかけます。"Middlewareを使う場合"の記事はそのうち書こうと思っています。 書きました。ReduxのcreateStore()の処理を追う(Middleware有りの場合)

この記事で解説する流れは、呼び出し元がこんな風に呼び出している場合を想定しています。

 // stateの初期状態無し
 let store = createStore(reducerA);
 // stateの初期状態あり
 let store = createStore(reducerA, preloadedState);

createStore()でやっている処理

引数の整理と型チェック

createStore()の最初は、引数preloadedStateとenhancerの内容を確認して、第二引数のpreloadedStateがfunctionだった場合には、これをenhancerとみなして変数の置き換えをやっています。
これは"Middlewareを使う場合"の呼び出し方に対応するためなので、Middlewareを使わないこの記事分では関係ありません。

関数の定義と変数の束縛

  let currentReducer = reducer
  let currentState = preloadedState
  let currentListeners = []
  let nextListeners = currentListeners
  let isDispatching = false
  function getState() {...}
  function subscribe(listener) {...}
  function dispatch(action) {...}
  function replaceReducer(nextReducer) {...}

createState()内で変数を保持しつつ、関数内関数としてgetState()、subscribe()、dispatch()、replaceReducer() を定義し、それぞれの関数の中で変数を束縛していきます。
こうすることで、同じ変数を中に持つ関数群が作成できます。
(この"束縛"関連の説明は、自分がJavaScriptの知識が曖昧なので自信がありません)

stateの初期化

 dispatch({ type: ActionTypes.INIT })

ActionTypes.INITは、redux組み込みのアクションのようです。ソースはutils/actionTypes.jsです。
通常Reducerは「変更前stateがnullだったらデフォルト値を設定する」「知らないアクションが来たらstateをそのまま返す」実装のはずなので、ActionTypes.INITで初期化されます。

面白いのは、ActionTypes.INITはランダムな文字が付与されています。おそらく、ユーザの定義と被らないようにしているのだと思います。
またActionTypes.REPLACE や ActionTypes.PROBE_UNKNOWN_ACTION というアクションも定義されています。これらはcombineReducers.jsの中で使われています。

Storeオブジェクトを組み立てて返す

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

戻り値としては、関数内関数をオブジェクトに割り当てて返しています。
この戻し方で、呼び出し元では store.dispatch(〜)という、「オブジェクトのメソッド呼び出し」のような見た目で各関数にアクセス出来るようになります。各関数は共通の変数を束縛しているので、あたかも「Javaのクラスをnewして作るオブジェクト」のように扱えます。

ここで返される関数のうち、最後の[$$observable]:observableは奇妙です。ここは今は追いかけない事にしています。

JavaScriptの仕様だと思うのですが、

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

と書かなくても、ちゃんと関数名で呼び出せるようになるのですね。この辺はまだ良くわかっていません。

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?