Skip to content

Commit dc11155

Browse files
committed
Adds docs and fix test.
1 parent c87f959 commit dc11155

File tree

4 files changed

+86
-4
lines changed

4 files changed

+86
-4
lines changed

docs/api/actionCreatorMiddleware.mdx

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
---
2+
id: actionCreatorMiddleware
3+
title: Action Creator Middleware
4+
sidebar_label: Action Creator Middleware
5+
hide_title: true
6+
---
7+
8+
 
9+
10+
# Action Creator Middleware
11+
12+
A custom middleware that detects if an action creator has been mistakenly dispatched, instead of being called before dispatching.
13+
14+
A common mistake is to call `dispatch(actionCreator)` instead of `dispatch(actionCreator())`.
15+
This tends to "work" as the action creator has the static `type` property, but can lead to unexpected behaviour.
16+
17+
## Options
18+
19+
```ts no-transpile
20+
export interface ActionCreatorInvariantMiddlewareOptions {
21+
/**
22+
* The function to identify whether a value is an action creator.
23+
* The default checks for a function with a static type property and match method.
24+
*/
25+
isActionCreator?: (action: unknown) => action is Function & { type?: unknown }
26+
}
27+
```
28+
29+
## Exports
30+
31+
### `createActionCreatorInvariantMiddleware`
32+
33+
Creates an instance of the action creator check middleware, with the given options.
34+
35+
You will most likely not need to call this yourself, as `getDefaultMiddleware` already does so.
36+
Example:
37+
38+
```ts
39+
// file: reducer.ts noEmit
40+
41+
export default function (state = {}, action: any) {
42+
return state
43+
}
44+
45+
// file: store.ts
46+
47+
import {
48+
configureStore,
49+
createActionCreatorInvariantMiddleware,
50+
} from '@reduxjs/toolkit'
51+
import reducer from './reducer'
52+
53+
// Augment middleware to consider all functions with a static type property to be action creators
54+
const isActionCreator = (
55+
action: unknown
56+
): action is Function & { type: unknown } =>
57+
typeof action === 'function' && 'type' in action
58+
59+
const actionCreatorMiddleware = createActionCreatorInvariantMiddleware({
60+
isActionCreator,
61+
})
62+
63+
const store = configureStore({
64+
reducer,
65+
middleware: [actionCreatorMiddleware],
66+
})
67+
```

docs/api/getDefaultMiddleware.mdx

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ It is preferable to use the chainable `.concat(...)` and `.prepend(...)` methods
7070

7171
One of the goals of Redux Toolkit is to provide opinionated defaults and prevent common mistakes. As part of that,
7272
`getDefaultMiddleware` includes some middleware that are added **in development builds of your app only** to
73-
provide runtime checks for two common issues:
73+
provide runtime checks for three common issues:
7474

7575
- [Immutability check middleware](./immutabilityMiddleware.mdx): deeply compares
7676
state values for mutations. It can detect mutations in reducers during a dispatch, and also mutations that occur between
@@ -82,13 +82,21 @@ provide runtime checks for two common issues:
8282
such as functions, Promises, Symbols, and other non-plain-JS-data values. When a non-serializable value is detected, a
8383
console error will be printed with the key path for where the non-serializable value was detected.
8484

85+
- [Action creator check middleware](./actionCreatorMiddleware.mdx): another custom middleware created specifically for use in Redux Toolkit.
86+
Identifies when an action creator was mistakenly dispatched without being called, and warns to console with the action type.
87+
8588
In addition to these development tool middleware, it also adds [`redux-thunk`](https://github.com/reduxjs/redux-thunk)
8689
by default, since thunks are the basic recommended side effects middleware for Redux.
8790

8891
Currently, the return value is:
8992

9093
```js
91-
const middleware = [thunk, immutableStateInvariant, serializableStateInvariant]
94+
const middleware = [
95+
immutableStateInvariant,
96+
thunk,
97+
serializableStateInvariant,
98+
actionCreatorInvariant,
99+
]
92100
```
93101

94102
### Production
@@ -153,10 +161,15 @@ interface SerializableStateInvariantMiddlewareOptions {
153161
// See "Serializability Middleware" page for definition
154162
}
155163

164+
interface ActionCreatorInvariantMiddlewareOptions {
165+
// See "Action Creator Middleware" page for definition
166+
}
167+
156168
interface GetDefaultMiddlewareOptions {
157169
thunk?: boolean | ThunkOptions
158170
immutableCheck?: boolean | ImmutableStateInvariantMiddlewareOptions
159171
serializableCheck?: boolean | SerializableStateInvariantMiddlewareOptions
172+
actionCreatorCheck?: boolean | ActionCreatorInvariantMiddlewareOptions
160173
}
161174

162175
function getDefaultMiddleware<S = any>(

packages/toolkit/src/tests/configureStore.test.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,10 @@ describe('configureStore', () => {
7575
Object
7676
)
7777
expect(redux.applyMiddleware).toHaveBeenCalledWith(
78-
expect.any(Function), // thunk
7978
expect.any(Function), // immutableCheck
80-
expect.any(Function) // serializableCheck
79+
expect.any(Function), // thunk
80+
expect.any(Function), // serializableCheck
81+
expect.any(Function) // actionCreatorCheck
8182
)
8283
expect(devtools.composeWithDevTools).toHaveBeenCalled() // @remap-prod-remove-line-line
8384
expect(redux.createStore).toHaveBeenCalledWith(

website/sidebars.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
"api/getDefaultMiddleware",
4242
"api/immutabilityMiddleware",
4343
"api/serializabilityMiddleware",
44+
"api/actionCreatorMiddleware",
4445
"api/createListenerMiddleware",
4546
"api/autoBatchEnhancer"
4647
]

0 commit comments

Comments
 (0)