You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/api/createAction.md
+78-26Lines changed: 78 additions & 26 deletions
Original file line number
Diff line number
Diff line change
@@ -7,44 +7,96 @@ hide_title: true
7
7
8
8
# `createAction`
9
9
10
-
A utility function to create an action creator for the given action type string. The action creator accepts a single argument, which will be included in the action object as a field called `payload`. The action creator function will also have its `toString()` overriden so that it returns the action type, allowing it to be used in reducer logic that is looking for that action type.
10
+
A helper function for defining a Redux [action](https://redux.js.org/basics/actions)type and creator.
11
11
12
12
```js
13
-
// actions.js
14
-
import { createAction } from'redux-starter-kit'
15
-
16
-
exportconstincrement=createAction('increment')
17
-
18
-
console.log(increment)
19
-
// "increment"
13
+
functioncreateAction(type)
14
+
```
20
15
21
-
consttheAction=increment(5)
22
-
console.log(theAction)
23
-
// {type : "increment", payload : 5}
16
+
The usual way to define an action in Redux is to separately declare an _action type_ constant and an _action creator_ function for constructing actions of that type.
24
17
25
-
// reducer.js
26
-
import { increment } from'./actions'
18
+
```js
19
+
const INCREMENT = 'counter/increment'
27
20
28
-
functioncounterReducer(state=0, action) {
29
-
switch (action.type) {
30
-
// action creator's `toString()` can be used as the type for comparisons
31
-
caseincrement.toString(): {
32
-
return state +action.payload
33
-
}
34
-
default:
35
-
return state
21
+
function increment(amount) {
22
+
return {
23
+
type:INCREMENT,
24
+
payload: amount
36
25
}
37
26
}
27
+
28
+
constaction=increment(3)
29
+
// { type: 'counter/increment', payload: 3 }
30
+
```
31
+
32
+
The `createAction` helper combines these two declarations into one. It takes an action type and returns an action creator for that type. The action creator can be called either without arguments or with a `payload` to be attached to the action. Also, the action creator overrides [toString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString) so that the action type becomes its string representation.
Because of their `toString()` override, action creators returned by `createAction()` can be used directly as keys for the case reducers passed to [createReducer()](createReducer.md).
53
+
54
+
```js
55
+
constincrement=createAction('counter/increment')
56
+
constdecrement=createAction('counter/decrement')
57
+
58
+
constcounterReducer=createReducer(0, {
59
+
[increment]: (state, action) => state +action.payload,
60
+
[decrement]: (state, action) => state -action.payload
61
+
})
62
+
```
63
+
64
+
This works because object keys that are not natively supported by JavaScript (like, in this case, functions) are implicitly converted to strings, and the action creators’ string representations happen to be the action types they produce.
65
+
66
+
## Non-String Action Types
67
+
68
+
In principle, Redux lets you use any kind of value as an action type. Instead of strings, you could theoretically use numbers, [symbols](https://developer.mozilla.org/en-US/docs/Glossary/Symbol), or anything else ([although it's recommended that the value should at least be serializable](https://redux.js.org/faq/actions#why-should-type-be-a-string-or-at-least-serializable-why-should-my-action-types-be-constants)).
69
+
70
+
However, `redux-starter-kit` rests on the assumption that you use string action types. Specifically, some of its features rely on the fact that with strings, the `toString()` method of an `createAction()` action creator returns the matching action type. This is not the case for non-string action types because `toString()` will return the string-converted type value rather than the type itself.
71
+
72
+
```js
73
+
constINCREMENT=Symbol('increment')
74
+
constincrement=createAction(INCREMENT)
75
+
76
+
increment.toString()
77
+
// returns the string 'Symbol(increment)',
78
+
// not the INCREMENT symbol itself
79
+
80
+
increment.toString() ===INCREMENT
81
+
// false
38
82
```
39
83
40
-
Since action creators returned by `createAction` have `toString()` overridden, they can be used in `createReducer`as a key in the `actionsMap`:
84
+
This means that, for instance, you cannot use a non-string-type action creator as a case reducer key for [createReducer()](createReducer.md).
41
85
42
86
```js
43
-
// reducer.js
44
-
import { createReducer } from'redux-starter-kit'
45
-
import { increment } from'./actions'
87
+
constINCREMENT=Symbol('increment')
88
+
constincrement=createAction(INCREMENT)
46
89
47
90
constcounterReducer=createReducer(0, {
48
-
[increment]: (state, action) => state +action.payload
91
+
// The following case reducer will NOT trigger for
92
+
// increment() actions because `increment` will be
93
+
// interpreted as a string, rather than being evaluated
94
+
// to the INCREMENT symbol.
95
+
[increment]: (state, action) => state +action.payload,
96
+
97
+
// You would need to use the action type explicitly instead.
98
+
[INCREMENT]: (state, action) => state +action.payload
49
99
})
50
100
```
101
+
102
+
For this reason, **we strongly recommend you to only use string action types**.
0 commit comments