Redux middleware
What is middleware?
Middleware is essentially a function, and Redux allows us to extend and enhance Redux applications in a middleware way, as demonstrated by the ability to handle actions, counters and pop-ups. Actions are directly processed by the Reducer function. After adding the middleware, this action will be processed by the reducer first. When this action is processed, the middleware will pass this action to the Reducer and let the reducer continue processing
Added middleware Redux workflow
Develop Redux middleware
Developing middleware template code is essentially a function, and is a corrified function
export default store => next= > action= > {}
Copy the code
In the innermost function we can execute our own business logic. In the outermost function we are provided with a parameter called store. We can use store.getState to get the current state. You can also use store.dispatch to trigger another action, depending on the business logic used. The innermost function also has a parameter, which is the action object triggered by the component, depending on action.type to determine whether the current action should be processed. The intermediate function also has a parameter, which is a function called next. After we finish executing the logic code, we need to call the next method to pass the current action to the reducer, or to the next middleware, because there can be multiple middleware. After the middleware is developed, we need to import the middleware we wrote and register it with Redux.
Registered middleware
import { createStore, applyMiddleware } from 'redux'
import logger from './middlewares/logger'
createStore(reducer, applyMiddleware(
logger
))
Copy the code
Developing a middleware
Implement a middleware that prints each action
- New SRC/store/middleware/logger. Js file, in this file export a middleware we print on here
// eslint-disable-next-line import/no-anonymous-default-export
export default store => next= > action= > {
console.log(store.getState())
console.log(action)
// Next must be called and action must be passed
next(action)
}
Copy the code
- Register middleware in store/index.js
import logger from './middleware/logger'
import { applyMiddleware } from 'redux'
export const store = createStore(RootReducer, applyMiddleware(logger))
Copy the code
This is when the middleware is ready to use. Running the project, you can see that the middleware is already working. A single middleware is registered, but how can multiple middleware be registered
- Our new SRC/store/middleware/test. The js files registered another middleware this test middleware to print in a word, and in the store/index, js to register the middleware, and exchange registration order to view the middleware execution order
//src/store/middleware/test.js
export default store => next= > action= > {
console.log('Test middleware')
next(action)
}
// src/store/index.js
import { createStore } from 'redux';
import RootReducer from './reducers/root.reducers'
import { applyMiddleware } from 'redux'
import logger from './middleware/logger'
import test from './middleware/test'
export const store = createStore(RootReducer, applyMiddleware(test ,logger))
Copy the code
It can be seen from the above that the execution order of middleware is the registration order
Develop the middleware instance Thunk
New requirements for counters
Click the +- button and delay execution by 2 seconds
The middleware intercepts the action of the addition or subtraction operation until the event arrives and then executes the next method
- New SRC/store/middleware/thunk. Js middleware, in this middleware intercept + – operation action delay two seconds to execute next method, and the store/index register the middleware in js files
// src/store/middleware/thunk.js
import { INCREMENT, DECREMENT } from '. /.. /const/counter.const'
export default store => next= > action= > {
if (action.type === INCREMENT || action.type === DECREMENT) {
setTimeout(() = > {
next(action)
}, 2000)}else{
next(action)
}
}
// SRC /store/index.js register middleware
import thunk from './middleware/thunk'
export const store = createStore(RootReducer, applyMiddleware(test, logger, thunk))
Copy the code
This is possible, but the code is not flexible enough. Middleware only focuses on whether the operation is asynchronous or synchronous so that the code is much more flexible
- Retrofit middleware
- When this middleware function doesn’t care what asynchronous operation you want to perform, just whether or not you are performing an asynchronous operation
- If you are performing an asynchronous operation, pass a function to the middleware when you trigger an action, and pass a normal action object if you are performing a synchronous operation
- The asynchronous operation code is written in the function passed in
- The current middleware function passes the dispatch method when it clicks on the function you passed in
import { INCREMENT, DECREMENT } from '. /.. /const/counter.const'
export default store => next= > action= > {
if (typeof action === 'function') {
return action(store.dispatch)
}
next(action)
}
Copy the code
- Add a new asynchronous function to the Action and bind the asynchronous function when the event is bound in the view
// src/store/actions/counter.actions.js
export const increment_async = payload= > dispatch= > {
setTimeout(() = > {
dispatch(increment(payload))
}, 2000);
}
// SRC /components/ count.js view to change binding events
function Count({count,increment_async,decrement}) {
return <div>
<button onClick={()= > increment_async(5)}>+</button>
<span>{count}</span>
<button onClick={()= > decrement(5)}>-</button>
</div>
}
Copy the code
So we don’t need to do the specific asynchronous operation in the middleware, we just need to determine whether it is asynchronous or synchronous operation in the middleware, execute the function we pass in and pass dispatch to the asynchronous function we pass in, execute the asynchronous operation in the asynchronous function, and trigger the real action
The original address: https://kspf.xyz/archives/20/