Skip to content

Commit

Permalink
feat: support extra thunk argument
Browse files Browse the repository at this point in the history
  • Loading branch information
jednano committed Aug 28, 2019
1 parent 987c21e commit 7705fcc
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 20 deletions.
19 changes: 16 additions & 3 deletions docs/api/configureStore.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ function configureStore({
middleware?: MiddlewareFunction[],
// Enable support for the Redux DevTools Extension. Defaults to true.
devTools?: boolean | EnhancerOptions,
// Same as current createStore.
// Same as current createStore
preloadedState?: State,
// An optional array of Redux store enhancers
enhancers?: ReduxStoreEnhancer[],
// Inject a custom thunk argument
extraThunkArgument?: any,
})
```

Expand Down Expand Up @@ -75,6 +77,10 @@ An optional array of Redux store enhancers. If included, these will be passed to
This should _not_ include `applyMiddleware()` or
the Redux DevTools Extension `composeWithDevTools`, as those are already handled by `configureStore`.

### `extraThunkArgument`

See [Redux Thunk | Injecting a Custom Argument](https://github.com/reduxjs/redux-thunk#injecting-a-custom-argument)

## Usage

### Basic Example
Expand Down Expand Up @@ -107,7 +113,10 @@ const reducer = {
visibility: visibilityReducer
}
const middleware = [...getDefaultMiddleware(), logger]
const middleware = [
...getDefaultMiddleware(/* extraThunkArgument */),
logger,
]
const preloadedState = {
todos: [
Expand All @@ -128,7 +137,11 @@ const store = configureStore({
middleware,
devTools: process.env.NODE_ENV !== 'production',
preloadedState,
enhancers: [reduxBatch]
enhancers: [reduxBatch],
/**
* Cannot provide both a middleware and an extraThunkArgument
*/
// extraThunkArgument: { api, whatever }
})
// The store has been created with these options:
Expand Down
48 changes: 31 additions & 17 deletions src/configureStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@ const IS_PRODUCTION = process.env.NODE_ENV === 'production'
*
* @return The default middleware used by `configureStore()`.
*/
export function getDefaultMiddleware<S = any, A extends Action = AnyAction>(): [
ThunkMiddleware<S, A>,
export function getDefaultMiddleware<S = any, A extends Action = AnyAction, E = any>(extraThunkArgument?: E): [
ThunkMiddleware<S, A, E>,
...Middleware<{}, S>[]
] {
let middlewareArray: [ThunkMiddleware<S, A>, ...Middleware<{}, S>[]] = [thunk]
let middlewareArray: [ThunkMiddleware<S, A, E>, ...Middleware<{}, S>[]] = [
extraThunkArgument ? thunk.withExtraArgument(extraThunkArgument) : thunk,
]

if (process.env.NODE_ENV !== 'production') {
/* START_REMOVE_UMD */
Expand All @@ -52,12 +54,12 @@ export function getDefaultMiddleware<S = any, A extends Action = AnyAction>(): [
/**
* Options for `configureStore()`.
*/
export interface ConfigureStoreOptions<S = any, A extends Action = AnyAction> {
export interface ConfigureStoreOptions<S = any, A extends Action = AnyAction, E = any> {
/**
* 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> | ReducersMapObject<S, A>
reducer?: Reducer<S, A> | ReducersMapObject<S, A>

/**
* An array of Redux middleware to install. If not supplied, defaults to
Expand Down Expand Up @@ -90,6 +92,12 @@ export interface ConfigureStoreOptions<S = any, A extends Action = AnyAction> {
* need to add middleware, you can use the `middleware` parameter instaead.
*/
enhancers?: StoreEnhancer[]

/**
* Inject a custom thunk argument.
* @see https://github.com/reduxjs/redux-thunk#injecting-a-custom-argument
*/
extraThunkArgument?: E
}

/**
Expand All @@ -107,16 +115,22 @@ export interface EnhancedStore<S = any, A extends Action = AnyAction>
* @param config The store configuration.
* @returns A configured Redux store.
*/
export function configureStore<S = any, A extends Action = AnyAction>(
options: ConfigureStoreOptions<S, A>
): EnhancedStore<S, A> {
export function configureStore<S = any, A extends Action = AnyAction, E = any>(
options: ConfigureStoreOptions<S, A, E> = {}
) {
const {
reducer = undefined,
middleware = getDefaultMiddleware(),
reducer,
devTools = true,
preloadedState = undefined,
enhancers = []
} = options || {}
preloadedState,
enhancers = [],
extraThunkArgument,
} = options

if (options.middleware && extraThunkArgument) {
throw new Error('Cannot supply both a middleware and an extraThunkArgument')
}

const middleware = options.middleware || getDefaultMiddleware(extraThunkArgument)

let rootReducer: Reducer<S, A>

Expand Down Expand Up @@ -144,11 +158,11 @@ export function configureStore<S = any, A extends Action = AnyAction>(

const storeEnhancers = [middlewareEnhancer, ...enhancers]

const composedEnhancer = finalCompose(...storeEnhancers) as StoreEnhancer
const composedEnhancer = finalCompose(...storeEnhancers)

return createStore(
return createStore<S, A, { dispatch: ThunkDispatch<S, E, A> }, unknown>(
rootReducer,
preloadedState as DeepPartial<S>,
composedEnhancer
preloadedState,
composedEnhancer as StoreEnhancer<{ dispatch: ThunkDispatch<S, E, A> }>
)
}

0 comments on commit 7705fcc

Please sign in to comment.