跳至主要內容

configureStore

建立 Redux store 的標準方法。它在內部使用低階 Redux 核心 createStore 方法,但會包裝它以提供良好的預設值給 store 設定,以獲得更好的開發體驗。

目的和行為

標準的 Redux store 設定通常需要多個設定項目

  • 將 slice reducer 結合到根 reducer
  • 建立 middleware enhancer,通常使用 thunk middleware 或其他 side effects middleware,以及可能用於開發檢查的 middleware
  • 加入 Redux DevTools enhancer,並組合 enhancer
  • 呼叫 createStore

傳統 Redux 使用模式通常需要複製貼上數十行樣板程式碼才能達成此目的。

Redux Toolkit 的 configureStore 簡化了設定流程,為您執行所有工作。呼叫 configureStore 一次將

  • 呼叫 combineReducers 將您的 slice reducer 合併到根 reducer 函式
  • 加入 thunk middleware 並呼叫 applyMiddleware
  • 在開發過程中,自動加入更多 middleware 來檢查常見錯誤,例如意外變更狀態
  • 自動設定 Redux DevTools Extension 連線
  • 呼叫 createStore 使用該根 reducer 和那些組態選項建立 Redux store

與原始 createStore 相比,configureStore 還提供改善的 API 和使用模式,它接受 reducerpreloadedStatemiddlewareenhancersdevtools 的命名欄位,以及更好的 TS 型別推論。

參數

configureStore 接受單一組態物件參數,其選項如下


interface ConfigureStoreOptions<
S = any,
A extends Action = UnknownAction,
M extends Tuple<Middlewares<S>> = Tuple<Middlewares<S>>
E extends Tuple<Enhancers> = Tuple<Enhancers>,
P = S
> {
/**
* A single reducer function that will be used as the root reducer, or an
* object of slice reducers that will be passed to `combineReducers()`.
*/
reducer: Reducer<S, A, P> | ReducersMapObject<S, A, P>

/**
* An array of Redux middleware to install. If not supplied, defaults to
* the set of middleware returned by `getDefaultMiddleware()`.
*/
middleware?: ((getDefaultMiddleware: CurriedGetDefaultMiddleware<S>) => M) | M

/**
* Whether to enable Redux DevTools integration. Defaults to `true`.
*
* Additional configuration can be done by passing Redux DevTools options
*/
devTools?: boolean | DevToolsOptions

/**
* The initial state, same as Redux's createStore.
* You may optionally specify it to hydrate the state
* from the server in universal apps, or to restore a previously serialized
* user session. If you use `combineReducers()` to produce the root reducer
* function (either directly or indirectly by passing an object as `reducer`),
* this must be an object with the same shape as the reducer map keys.
*/
preloadedState?: P

/**
* The store enhancers to apply. See Redux's `createStore()`.
* All enhancers will be included before the DevTools Extension enhancer.
* If you need to customize the order of enhancers, supply a callback
* function that will receive the getDefaultEnhancers,
* and should return a new array (such as `getDefaultEnhancers().concat(offline)`).
* If you only need to add middleware, you can use the `middleware` parameter instead.
*/
enhancers?: (getDefaultEnhancers: GetDefaultEnhancers<M>) => E | E
}

function configureStore<
S = any,
A extends Action = UnknownAction,
M extends Tuple<Middlewares<S>> = Tuple<Middlewares<S>>
E extends Tuple<Enhancers> = Tuple<Enhancers>,
P = S
>(options: ConfigureStoreOptions<S, A, M, E, P>): EnhancedStore<S, A, M, E>

reducer

如果這是一個單一函式,它將直接用作 store 的根 reducer。

如果它是一個 slice reducer 物件,例如 {users : usersReducer, posts : postsReducer}configureStore 將自動建立根 reducer,方法是將此物件傳遞給 Redux combineReducers 工具程式

middleware

一個會接收 getDefaultMiddleware 作為其參數的回呼,並應傳回一個 middleware 陣列。

如果提供此選項,它應傳回您要加入 store 的所有 middleware 函式。configureStore 將自動將它們傳遞給 applyMiddleware

如果未提供,configureStore 將呼叫 getDefaultMiddleware 並使用它傳回的中介軟體函式陣列。

有關 middleware 參數如何運作以及預設新增的中介軟體清單的更多詳細資訊,請參閱 getDefaultMiddleware 文件頁面

元組

建議 Typescript 使用者使用 Tuple 執行個體(如果沒有使用 getDefaultMiddleware 結果,它已經是 Tuple),以獲得更好的推論。

import { configureStore, Tuple } from '@reduxjs/toolkit'

configureStore({
reducer: rootReducer,
middleware: () => new Tuple(additionalMiddleware, logger),
})

僅限 Javascript 的使用者可以自由使用純粹陣列(如果偏好)。

devTools

如果這是一個布林值,它將用於指示 configureStore 是否應自動啟用對 Redux DevTools 瀏覽器擴充功能 的支援。

如果它是一個物件,則 DevTools 擴充功能將被啟用,並且選項物件將傳遞給 composeWithDevtools()。請參閱 DevTools 擴充功能文件,以取得 EnhancerOptions,以取得可用的特定選項清單。

預設為 true

trace

Redux DevTools 擴充功能最近新增 顯示動作堆疊追蹤 的支援,顯示每個動作的確切觸發位置。擷取追蹤可能會增加一些負擔,因此 DevTools 擴充功能允許使用者設定是否透過 設定「trace」參數 來擷取動作堆疊追蹤。如果透過傳遞 true 或物件來啟用 DevTools,則 configureStore 預設會啟用在開發模式下擷取動作堆疊追蹤。

preloadedState

傳遞給 Redux createStore 函式的選用初始狀態值。

enhancers

自訂增強器陣列的回呼函式。

此回呼函式回傳的增強器會傳遞至 Redux compose 函式,而合併後的增強器會傳遞至 createStore

開發人員工具

不應該包含 Redux DevTools Extension composeWithDevTools,因為這已經由 configureStore 處理。

範例:enhancers: () => new Tuple(offline) 會產生 [offline, devToolsExtension] 的最終設定。

如果未提供,configureStore 會呼叫 getDefaultEnhancers 並使用它回傳的增強器陣列(包含指定中間件的 applyMiddleware)。

如果您希望新增或自訂預設增強器,可以傳遞一個回呼函式,它會接收 getDefaultEnhancers 作為其引數,並應回傳一個增強器陣列。

範例:enhancers: (defaultEnhancers) => defaultEnhancers.prepend(offline) 會產生 [offline, applyMiddleware, devToolsExtension] 的最終設定。

有關 enhancer 參數如何運作以及預設新增的增強器清單的更多詳細資訊,請參閱 getDefaultEnhancers 文件頁面

中間件

如果您不使用 getDefaultEnhancers 而改為回傳陣列,則不會使用 applyMiddleware 增強器。

如果提供任何中間件(或保留為預設值)但未包含在增強器的最終清單中,configureStore 會在主控台中發出警告。

// warns - middleware customised but not included in final enhancers
configureStore({
reducer,
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(logger)
enhancers: [offline(offlineConfig)],
})

// fine - default enhancers included
configureStore({
reducer,
enhancers: (getDefaultEnhancers) => getDefaultEnhancers().concat(offline(offlineConfig)),
})

// also allowed
configureStore({
reducer,
middleware: () => [],
enhancers: () => [offline(offlineConfig)],
})

請注意,如果使用 Typescript,則 middleware 選項必須在增強器選項之前提供,因為 getDefaultEnhancers 的類型取決於其結果。

元組

Typescript 使用者必須使用 Tuple 實例(如果未使用 getDefaultEnhancer 結果,它已經是 Tuple),以獲得更好的推論。

import { configureStore, Tuple } from '@reduxjs/toolkit'

configureStore({
reducer: rootReducer,
enhancers: () => new Tuple(offline),
})

僅限 Javascript 的使用者可以自由使用純粹陣列(如果偏好)。

用法

基本範例

import { configureStore } from '@reduxjs/toolkit'

import rootReducer from './reducers'

const store = configureStore({ reducer: rootReducer })
// The store now has redux-thunk added and the Redux DevTools Extension is turned on

完整範例

// file: todos/todosReducer.ts noEmit
import type { Reducer } from '@reduxjs/toolkit'
declare const reducer: Reducer<{}>
export default reducer

// file: visibility/visibilityReducer.ts noEmit
import type { Reducer } from '@reduxjs/toolkit'
declare const reducer: Reducer<{}>
export default reducer

// file: store.ts
import { configureStore } from '@reduxjs/toolkit'

// We'll use redux-logger just as an example of adding another middleware
import logger from 'redux-logger'

// And use redux-batched-subscribe as an example of adding enhancers
import { batchedSubscribe } from 'redux-batched-subscribe'

import todosReducer from './todos/todosReducer'
import visibilityReducer from './visibility/visibilityReducer'

const reducer = {
todos: todosReducer,
visibility: visibilityReducer,
}

const preloadedState = {
todos: [
{
text: 'Eat food',
completed: true,
},
{
text: 'Exercise',
completed: false,
},
],
visibilityFilter: 'SHOW_COMPLETED',
}

const debounceNotify = _.debounce((notify) => notify())

const store = configureStore({
reducer,
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(logger),
devTools: process.env.NODE_ENV !== 'production',
preloadedState,
enhancers: (getDefaultEnhancers) =>
getDefaultEnhancers({
autoBatch: false,
}).concat(batchedSubscribe(debounceNotify)),
})

// The store has been created with these options:
// - The slice reducers were automatically passed to combineReducers()
// - redux-thunk and redux-logger were added as middleware
// - The Redux DevTools Extension is disabled for production
// - The middleware, batched subscribe, and devtools enhancers were composed together