Skip to content

Commit 3824a21

Browse files
Addresses #959 without affecting the library's existing functionality. Ultimately tries to prevent re-renders when multiple states are needed in quick succession.
1 parent 4b63737 commit 3824a21

File tree

2 files changed

+50
-26
lines changed

2 files changed

+50
-26
lines changed

src/createStore.js

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ export default function createStore(reducer, preloadedState, enhancer) {
122122
}
123123

124124
/**
125-
* Dispatches an action. It is the only way to trigger a state change.
125+
* Dispatches action(s). It is the only way to trigger a state change.
126126
*
127127
* The `reducer` function, used to create the store, will be called with the
128128
* current state tree and the given `action`. Its return value will
@@ -139,45 +139,55 @@ export default function createStore(reducer, preloadedState, enhancer) {
139139
* a good idea to keep actions serializable so you can record and replay user
140140
* sessions, or use the time travelling `redux-devtools`. An action must have
141141
* a `type` property which may not be `undefined`. It is a good idea to use
142-
* string constants for action types.
142+
* string constants for action types. Can handle multiple dispatches so to
143+
* keep re-renders at a minimum.
143144
*
144-
* @returns {Object} For convenience, the same action object you dispatched.
145+
* @returns {Object|Array} For convenience, the same action object you dispatched.
146+
* If multiple actions are supplied, then will be returned as an Array.
145147
*
146148
* Note that, if you use a custom middleware, it may wrap `dispatch()` to
147149
* return something else (for example, a Promise you can await).
148150
*/
149-
function dispatch(action) {
150-
if (!isPlainObject(action)) {
151-
throw new Error(
152-
'Actions must be plain objects. ' +
153-
'Use custom middleware for async actions.'
154-
)
155-
}
151+
function dispatch() {
152+
var actions = []
153+
var i;
154+
for (i = 0; i < arguments.length; i++) {
155+
var action = arguments[i]
156156

157-
if (typeof action.type === 'undefined') {
158-
throw new Error(
159-
'Actions may not have an undefined "type" property. ' +
160-
'Have you misspelled a constant?'
161-
)
162-
}
157+
if (!isPlainObject(action)) {
158+
throw new Error(
159+
'Actions must be plain objects. ' +
160+
'Use custom middleware for async actions.'
161+
)
162+
}
163163

164-
if (isDispatching) {
165-
throw new Error('Reducers may not dispatch actions.')
166-
}
164+
if (typeof action.type === 'undefined') {
165+
throw new Error(
166+
'Actions may not have an undefined "type" property. ' +
167+
'Have you misspelled a constant?'
168+
)
169+
}
170+
171+
if (isDispatching) {
172+
throw new Error('Reducers may not dispatch actions.')
173+
}
174+
175+
try {
176+
isDispatching = true
177+
currentState = currentReducer(currentState, action)
178+
} finally {
179+
isDispatching = false
180+
}
167181

168-
try {
169-
isDispatching = true
170-
currentState = currentReducer(currentState, action)
171-
} finally {
172-
isDispatching = false
182+
actions.push(action)
173183
}
174184

175185
var listeners = currentListeners = nextListeners
176-
for (var i = 0; i < listeners.length; i++) {
186+
for (i = 0; i < listeners.length; i++) {
177187
listeners[i]()
178188
}
179189

180-
return action
190+
return actions.length > 1 ? actions : actions[0]
181191
}
182192

183193
/**

test/createStore.spec.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,20 @@ describe('createStore', () => {
7777
])
7878
})
7979

80+
it('can handle multiple dispatches', () => {
81+
const store = createStore(reducers.todos)
82+
store.dispatch(addTodo('Hello'), addTodo('World'))
83+
expect(store.getState()).toEqual([
84+
{
85+
id: 1,
86+
text: 'Hello'
87+
}, {
88+
id: 2,
89+
text: 'World'
90+
}
91+
])
92+
})
93+
8094
it('applies the reducer to the initial state', () => {
8195
const store = createStore(reducers.todos, [
8296
{

0 commit comments

Comments
 (0)