名詞解釋
這是 Redux 中核心名詞的用語表,包含其型別簽章。型別使用 Flow 符號 記錄。
狀態
type State = any
狀態(也稱為狀態樹)是一個廣義的用語,但在 Redux API 中,它通常是指由儲存庫管理並由 getState()
傳回的單一狀態值。它代表 Redux 應用程式的完整狀態,通常是一個深度巢狀的物件。
根據慣例,頂層狀態是一個物件或其他類似 Map 的鍵值集合,但技術上來說,它可以是任何型別。不過,你應該盡力讓狀態可序列化。不要在其中放入任何無法輕易轉換為 JSON 的內容。
動作
type Action = Object
動作是表示變更狀態意圖的純粹物件。動作是將資料放入儲存的唯一方式。任何資料,無論來自使用者介面事件、網路回呼或其他來源(例如 WebSockets),最終都必須作為動作發送。
動作必須具有 type
欄位,用來表示執行的動作類型。類型可以定義為常數,並從其他模組匯入。最好將字串用於 type
,而不是 符號,因為字串是可序列化。
除了 type
之外,動作物件的結構完全取決於您。如果您有興趣,請查看 Flux 標準動作,了解如何建構動作的建議。
另請參閱下方的 非同步動作。
Reducer
type Reducer<S, A> = (state: S, action: A) => S
Reducer 是接受累積和值並傳回新累積的函式。它們用於將值集合簡化為單一值。
Reducer 不僅限於 Redux,它們是函式程式設計中的基本概念。即使大多數非函式語言(例如 JavaScript)都內建有簡化的 API。在 JavaScript 中,它是 Array.prototype.reduce()
。
在 Redux 中,累積值是狀態物件,而累積的值是動作。Reducer 會根據前一個狀態和動作計算新的狀態。它們必須是純粹函式,也就是對於給定的輸入傳回完全相同輸出的函式。它們也應該沒有副作用。這可啟用熱重載和時間旅行等令人興奮的功能。
Reducer 是 Redux 中最重要的概念。
不要將 API 呼叫放入 Reducer。
Dispatching Function
type BaseDispatch = (a: Action) => Action
type Dispatch = (a: Action | AsyncAction) => any
Dispatching 函式(或簡稱dispatch 函式)是接受動作或 非同步動作 的函式;然後它可能會或可能不會將一個或多個動作發送到儲存。
我們必須區分一般的 dispatching 函式和由儲存實例提供的基本 dispatch
函式(沒有任何中間件)。
基本 dispatch 函數永遠會同步將動作傳送至商店的 reducer,連同商店回傳的前一個狀態,以計算新的狀態。它預期動作是準備好讓 reducer 使用的純粹物件。
Middleware 包裝基本 dispatch 函數。它允許 dispatch 函數處理 非同步動作,以及動作。Middleware 可以在將動作或非同步動作傳遞至下一個 middleware 之前,轉換、延遲、忽略或以其他方式詮釋動作或非同步動作。請參閱下方以取得更多資訊。
動作建立函數
type ActionCreator<A, P extends any[] = any[]> = (...args: P) => Action | AsyncAction
動作建立函數,簡單來說,就是建立動作的函數。不要混淆這兩個術語,再次說明,動作是資訊的酬載,而動作建立函數是建立動作的工廠。
呼叫動作建立函數只會產生動作,但不會 dispatch 動作。您需要呼叫商店的 dispatch
函數,才能實際造成變異。有時我們會說約束動作建立函數,表示呼叫動作建立函數,並立即將其結果 dispatch 至特定商店實例的函數。
如果動作建立函數需要讀取目前狀態、執行 API 呼叫,或造成副作用,例如路由轉換,它應該回傳 非同步動作,而不是動作。
非同步動作
type AsyncAction = any
非同步動作是傳送至 dispatching 函數的值,但尚未準備好讓 reducer 使用。它會由 middleware 轉換為動作(或一系列動作),然後再傳送至基本 dispatch()
函數。非同步動作可能有不同的類型,視您使用的 middleware 而定。它們通常是非同步原語,例如 Promise 或 thunk,不會立即傳遞至 reducer,而是在操作完成後觸發動作 dispatch。
Middleware
type MiddlewareAPI = { dispatch: Dispatch, getState: () => State }
type Middleware = (api: MiddlewareAPI) => (next: Dispatch) => Dispatch
Middleware 是高階函數,用來組合 dispatch 函數 以回傳新的 dispatch 函數。它通常會將 非同步動作 轉換為動作。
Middleware 可以使用函數組合進行組合。它對於記錄動作、執行路由等副作用,或將非同步 API 呼叫轉換為一系列同步動作很有用。
請參閱 applyMiddleware(...middlewares)
以詳細了解中間件。
儲存
type Store = {
dispatch: Dispatch
getState: () => State
subscribe: (listener: () => void) => () => void
replaceReducer: (reducer: Reducer) => void
}
儲存是一個包含應用程式狀態樹的物件。Redux 應用程式中應只有一個儲存,因為組合發生在 reducer 層級。
dispatch(action)
是上面描述的基本發送函式。getState()
傳回儲存的目前狀態。subscribe(listener)
註冊一個函式,以便在狀態變更時呼叫。replaceReducer(nextReducer)
可用於實作熱重載和程式碼拆分。您很可能不會使用它。
請參閱完整的 儲存 API 參考 以取得更多詳細資訊。
儲存建立器
type StoreCreator = (reducer: Reducer, preloadedState: ?State) => Store
儲存建立器是一個建立 Redux 儲存的函式。與發送函式一樣,我們必須區分基本儲存建立器 createStore(reducer, preloadedState)
(從 Redux 套件匯出)和從儲存增強器傳回的儲存建立器。
儲存增強器
type StoreEnhancer = (next: StoreCreator) => StoreCreator
儲存增強器是一個高階函式,用於組合儲存建立器以傳回新的增強儲存建立器。這類似於中間件,因為它允許您以可組合的方式變更儲存介面。
儲存增強器的概念與 React 中的高階元件非常相似,後者有時也稱為「元件增強器」。
由於儲存不是一個實例,而是一個純粹物件的函式集合,因此可以輕鬆建立和修改副本,而不會變異原始儲存。在 compose
文件中有一個範例說明這一點。
您很可能永遠不會撰寫儲存增強器,但您可以使用 開發人員工具 提供的增強器。它讓時間旅行成為可能,而應用程式並不知道它正在發生。有趣的是,Redux 中間件實作 本身就是一個儲存增強器。