middlewares intercept actions, modify them, or cancel them by not calling any of the next middleware.
Basically, middleware happens between dispatching an action, and the moment it reaches the reducer.
1// Create a middleware
2// Logger
3const logger = store => next => action => {
4 console.log('action fired', action)
5 next(action)
6}
7
8// Apply middleware
9const middleware = applyMiddleware(logger)
10
11// create the store, pass it the middleware along with reducers and state
12const store = createStore(reducer, 1, middleware)
You’re probably never gonna create middleware, you’ll just npm install them. For example, redux-logger
gives you very nice console logs about state changes. redux-thunk
is another one that let’s you send multiple dispatch()
functions asynchronously
redux-thunk
1import thunk from `redux-thunk`
2
3const middleware = applyMiddleware(thunk)
4const store = createStore(reducer, 1, middleware)
5
6store.subscribe(() => {
7 console.log('store changed', store.getState())
8})
9
10store.dispatch((dispatch) => {
11 dispatch({type: 'INC'})
12 dispatch({type: 'FOO'})
13 dispatch({type: 'BAR'})
14 dispatch({type: 'DEC'})
15 dispatch({type: 'BAZ'})
16 dispatch({type: 'DEC'})
17 dispatch({type: 'E'})
18})
All the dispatch function above will be called async. Multiple actions are happening with one single action.
1// Send actions
2store.dispatch({type: 'INC'})
3store.dispatch({type: 'FOO'})
4store.dispatch({type: 'BAR'})
5store.dispatch({type: 'DEC'})
6store.dispatch({type: 'BAZ'})
7store.dispatch({type: 'DEC'})
8store.dispatch({type: 'E'})
will become
1store.dispatch((dispatch) => {
2 dispatch({type: 'INC'})
3 dispatch({type: 'FOO'})
4 dispatch({type: 'BAR'})
5 dispatch({type: 'DEC'})
6 dispatch({type: 'BAZ'})
7 dispatch({type: 'DEC'})
8 dispatch({type: 'E'})
9})