用語集
これはReduxのコアとなる用語とその型シグネチャの用語集です。型はFlow記法を使用して記述されています。
ステート
type State = any
ステート(ステートツリーとも呼ばれる)は広義の用語ですが、Redux APIでは通常、ストアによって管理され、getState()
によって返される単一のステート値を指します。これは、多くの場合、深くネストされたオブジェクトであるReduxアプリケーションの全体のステートを表します。
慣例により、トップレベルのステートはオブジェクトまたはMapのような他のキーバリューコレクションですが、技術的には任意の型にすることができます。それでも、ステートはシリアライズ可能に保つように最善を尽くしてください。簡単にJSONに変換できないものは何も入れないでください。
アクション
type Action = Object
アクションは、ステートを変更する意図を表すプレーンオブジェクトです。アクションは、ストアにデータを取得する唯一の方法です。UIイベント、ネットワークコールバック、またはWebSocketなどの他のソースからのデータは、最終的にアクションとしてディスパッチされる必要があります。
アクションには、実行されているアクションのタイプを示すtype
フィールドが必要です。型は定数として定義し、別のモジュールからインポートできます。文字列はシリアライズ可能であるため、type
にはシンボルよりも文字列を使用する方が適切です。
type
以外のアクションオブジェクトの構造は、実際にはあなた次第です。興味があれば、アクションの構築方法に関する推奨事項については、Flux Standard Actionをご覧ください。
以下の非同期アクションも参照してください。
レデューサー
type Reducer<S, A> = (state: S, action: A) => S
レデューサーは、累積値と値を受け取り、新しい累積値を返す関数です。これらは、値のコレクションを単一の値に減らすために使用されます。
レデューサーはRedux固有のものではなく、関数型プログラミングの基本的な概念です。JavaScriptのような非関数型言語のほとんどにも、削減のための組み込みAPIがあります。JavaScriptでは、Array.prototype.reduce()
です。
Reduxでは、累積値はステートオブジェクトであり、累積される値はアクションです。レデューサーは、前のステートとアクションを考慮して新しいステートを計算します。それらは、指定された入力に対してまったく同じ出力を返す関数である*純粋関数*でなければなりません。また、副作用があってはなりません。ホットリロードやタイムトラベルなどの刺激的な機能を可能にするのはこれです。
レデューサーはReduxで最も重要な概念です。
レデューサーにAPIコールを入れないでください。
ディスパッチ関数
type BaseDispatch = (a: Action) => Action
type Dispatch = (a: Action | AsyncAction) => any
*ディスパッチ関数*(または単に*ディスパッチ関数*)とは、アクションまたは非同期アクションを受け入れる関数です。その後、ストアに1つ以上のアクションをディスパッチする場合としない場合があります。
一般的なディスパッチ関数と、ミドルウェアなしでストアインスタンスによって提供される基本的なdispatch
関数を区別する必要があります。
基本ディスパッチ関数は、*常に*同期的にアクションをストアのレデューサーに送信し、ストアによって返された前のステートとともに、新しいステートを計算します。アクションは、レデューサーによって消費される準備ができているプレーンオブジェクトであると想定しています。
ミドルウェアは、基本ディスパッチ関数をラップします。これにより、ディスパッチ関数はアクションに加えて非同期アクションを処理できます。ミドルウェアは、アクションまたは非同期アクションを次のミドルウェアに渡す前に、変換、遅延、無視、またはその他の方法で解釈する場合があります。詳細については、以下を参照してください。
アクションクリエイター
type ActionCreator<A, P extends any[] = any[]> = (...args: P) => Action | AsyncAction
*アクションクリエイター*は、ごく簡単に言うと、アクションを作成する関数です。2つの用語を混同しないでください。繰り返しますが、アクションは情報のペイロードであり、アクションクリエイターはアクションを作成するファクトリです。
アクションクリエイターを呼び出すと、アクションが生成されるだけですが、ディスパッチされません。実際に突然変異を起こすには、ストアのdispatch
関数を呼び出す必要があります。アクションクリエイターを呼び出して、その結果を特定のストアインスタンスにすぐにディスパッチする関数を*バインドされたアクションクリエイター*と呼ぶこともあります。
アクションクリエイターが現在の状態を読み取る、API呼び出しを実行する、またはルーティング遷移などの副作用を引き起こす必要がある場合は、アクションの代わりに非同期アクションを返す必要があります。
非同期アクション
type AsyncAction = any
*非同期アクション*は、ディスパッチ関数に送信されるが、レデューサーによる消費の準備がまだできていない値です。基本dispatch()
関数に送信される前に、ミドルウェアによってアクション(または一連のアクション)に変換されます。非同期アクションは、使用するミドルウェアに応じて、異なるタイプを持つ場合があります。それらは多くの場合、Promiseやthunkのような非同期プリミティブであり、レデューサーにすぐに渡されるのではなく、操作が完了するとアクションディスパッチをトリガーします。
ミドルウェア
type MiddlewareAPI = { dispatch: Dispatch, getState: () => State }
type Middleware = (api: MiddlewareAPI) => (next: Dispatch) => Dispatch
ミドルウェアは、ディスパッチ関数を構成して新しいディスパッチ関数を返す高階関数です。多くの場合、非同期アクションをアクションに変えます。
ミドルウェアは、関数合成を使用して合成できます。アクションのログ記録、ルーティングなどの副作用の実行、または非同期API呼び出しを一連の同期アクションに変換するのに役立ちます。
ミドルウェアの詳細については、applyMiddleware(...middlewares)
を参照してください。
ストア
type Store = {
dispatch: Dispatch
getState: () => State
subscribe: (listener: () => void) => () => void
replaceReducer: (reducer: Reducer) => void
}
ストアは、アプリケーションのステートツリーを保持するオブジェクトです。合成はレデューサーレベルで行われるため、Reduxアプリにはストアが1つだけ存在する必要があります。
dispatch(action)
は、上記の基盤となるディスパッチ関数です。getState()
は、ストアの現在のステートを返します。subscribe(listener)
は、ステートの変更時に呼び出される関数を登録します。replaceReducer(nextReducer)
は、ホットリロードとコード分割を実装するために使用できます。おそらく使用しないでしょう。
詳細については、完全なストアAPIリファレンスを参照してください。
ストアクリエイター
type StoreCreator = (reducer: Reducer, preloadedState: ?State) => Store
ストアクリエイターとは、Reduxストアを作成する関数です。ディスパッチ関数と同様に、Reduxパッケージからエクスポートされた基本ストアクリエイターであるcreateStore(reducer, preloadedState)
と、ストアエンハンサーから返されるストアクリエイターを区別する必要があります。
ストアエンハンサー
type StoreEnhancer = (next: StoreCreator) => StoreCreator
ストアエンハンサーは、ストアクリエイターを構成して新しい拡張ストアクリエイターを返す高階関数です。これはミドルウェアに似ており、ストアインターフェースを構成可能な方法で変更できます。
ストアエンハンサーは、Reactの高階コンポーネントとほぼ同じ概念であり、「コンポーネントエンハンサー」と呼ばれることもあります。
ストアはインスタンスではなく、関数のプレーンオブジェクトコレクションであるため、元のストアを変更せずにコピーを簡単に作成および変更できます。compose
ドキュメントには、それを示す例があります。
ストアエンハンサーを作成することはほとんどないでしょうが、開発ツールによって提供されるものを使用する場合があります。アプリが何が起こっているかを知らずにタイムトラベルを可能にするのはこれです。おもしろいことに、Reduxミドルウェアの実装自体がストアエンハンサーです。