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

  1. 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
  1. 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

  1. 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

  1. 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

  1. Retrofit middleware
  1. When this middleware function doesn’t care what asynchronous operation you want to perform, just whether or not you are performing an asynchronous operation
  2. 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
  3. The asynchronous operation code is written in the function passed in
  4. 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
  1. 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/