Experience of adding finally method to Axios and Redux Axios Middleware

Time:2021-12-31

Recently, the company asked react to write a nailed micro application app, and then we had to learn react. Before, we had always used angular and Vue, so asynchronous requests used jQuery and Axios. If we wanted to turn around, we directly used Axios. Then we found the Redux middleware of Axios on the Internet

Axios implements the finally method

Implementation 1 – q.js

At first, Axios was used. Because there was no finally method, it was always a little awkward to write, so it was introducedq.jsYou need to encapsulate all requests with q.promise, like this

//Definition
export function getUserInfo() {
    return Q.Promise((success, error) => {
        axios.post('[url]').then(function (data) {
            if (data.code == 200) {
                success(data.data)
            } else {
                error()
            }
        }).catch(function (err) {
            error()
        });
    })
}

//Use
getUserInfo()
    .then(()=>{
    })
    .catch(()=>{
    })
    .finally(()=>{
    })

Implementation 2 – promise prototype. finally

Finally, I’m looking at AxiosissuesWhen I accidentally saw someone asking a question, it was very simple after I realized the extension of es6promise with this library

//Just introduce this module and use this method
require('promise.prototype.finally').shim() 


//Use
axios.post('[url]')
    .then((data)=> {
    })
    .catch((err)=> {
    })
    .finally(()=> {
    })

Implementation of finally method with Redux Axios Middleware

When we do business, we must have the loading variable. We need to make the loading box appear before the request and hide it after completion
If you do not configure Redux Axios middleware, you can see that it has been written twicestate.setIn(['obj', 'loading'], false);

case 'GET_CATEGORY_LIST':
    return state.setIn(['obj', 'loading'], true);
    break;
case 'GET_CATEGORY_LIST_SUCCESS':
    state = state.setIn(['obj', 'list'], fromJS(aciton.payload.data))
    return state.setIn(['obj', 'loading'], false);
    break;
case 'GET_CATEGORY_LIST_FAIL':
    return state.setIn(['obj', 'loading'], false);
    break;

Configure Redux Axios Middleware

After looking at the source code, he has oneonCompleteMethods can be defined as follows

#axiosMiddlewareOptions.js
import { getActionTypes } from 'redux-axios-middleware/lib/getActionTypes'

export const returnRejectedPromiseOnError = true;

export const onComplete = ( { action, next, getState, dispatch }, actionOptions) => {
    const previousAction = action.meta.previousAction;
    const nextAction = {
        type: getActionTypes(previousAction, actionOptions)[0]+'_COMPLETE',
        meta: {
            previousAction: previousAction
        }
    };
    next(nextAction);
    return nextAction;
};
#store.js
import { createStore, compose, applyMiddleware } from 'redux'

import axios from 'axios';
import axiosMiddleware from 'redux-axios-middleware';
import * as axiosMiddlewareOptions from './common/axiosMiddlewareOptions'

const enhancers = compose(
    applyMiddleware(
        Axiosmiddleware (Axios, {... Axiosmiddlewareoptions}), // Axios Middleware
    ),
    window.devToolsExtension ? window.devToolsExtension() : f=>f
);

After this configuration, the Axios middleware will execute one every time the request is completed[type]_COMPLETEThe above reducer can be optimized as (if it is not handled for errors, it will generally be done in the interceptors of Axios)

case 'GET_CATEGORY_LIST':
    return state.setIn(['obj', 'loading'], true);
    break;
case 'GET_CATEGORY_LIST_SUCCESS':
    return state.setIn(['obj', 'list'], fromJS(aciton.payload.data))
    break;
case 'GET_CATEGORY_LIST_COMPLETE':
    return state.setIn(['obj', 'loading'], false);
    break;

There is also a configuration aboveexport const returnRejectedPromiseOnError = true;Its function is to make the catch method when the Axios middleware request is wrong, which can make the code structure clearer.

#Redux Axios middleware source code
return actionOptions.returnRejectedPromiseOnError ? Promise.reject(newAction) : newAction;

Then you can use Axios middleware to request better business code. The above is about the data in redux. The following is how to better control the data in state. The following three methods are actually Axios Request () method. Since we added the finally method to promise using the second method, we can use it like this now

this.setState({ refreshing: true });
this.props.userHome()
    .then(()=>{
        
    })
    .catch(()=>{
    })
    .finally(()=>{
        this.setState({ refreshing: false });
    })

OK, it’s over