react redux asynchronous Action

The last two articles describe synchronous operations, where the state is updated immediately when a dispatch action is taken. But

in practice, we have a lot of operations that take a while to get the result after execution. So how to deal with this situation?

Let’s get familiar with a concept called “middleware”.

Essentially a generic function that can intervene at any execution of the program, thus extending the processing to existing systems.

// Print the log when store.dispatch(action) is executed, which is a simple middleware.

let next = store.dispatch;
store.dispatch = action => {
  next(action);
  console.log('state after dispatch', getState())
}

Introducing middleware redux-thunk

The redux-thunk middleware, allows the action creator to return a function that takes dispath and getState as arguments.

// Look at the three different actions below
const INCREMENT_COUNTER = 'INCREMENT_COUNTER';

// Normal, returns an object
function increment() {
  return {
    type: INCREMENT_COUNTER
  };
}

// Asynchronous, returns a function
function incrementAsync() {
  return dispatch => {
    setTimeout(() => {
      // Yay! Can invoke sync or async actions with `dispatch`
      dispatch(increment());
    }, 1000);
  };
}


// Conditional, returns a function
function incrementIfOdd() {
  return (dispatch, getState) => {
    const { counter } = getState();

    if (counter % 2 === 0) {
      return;
    }

    dispatch(increment());
  };
}

Using middleware redux-thunk

Requirement:After entering the page, click on a button to get the total amount invested by the user.

Analysis:The asynchronous request has 3 key actions

  • Start request – generally used to present the loading progress bar
  • Successful request – closes the progress bar and loads the data
  • Request fails – closes the progress bar and presents the error message
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk'; // Importing thunk
import rootReducer from './reducers/index';

// Note: this API requires redux@>=3.1.0
const store = createStore(
  rootReducer,
  applyMiddleware(thunk)// Activate thunk middleware
);

// An asynchronous request
function fetchAmount() {
  return fetch('https://www.google.com/getAmount?userId=123')
}
// Notify the reducer of the action to start the request
requestPost(){
    return{
        type: REQUEST_POSTS,
        isFetch:true // Progress bar related
    }
}

// Action to notify the reducer of a successful request
receviePostOnSuccess( data){
    return{
         type: RECEIVE_POSTS,
         isFetch:false,
         amount: data.amount
     }
}
// Notify the reducer of a failed action request.
receviePostOnError( message){
  return{
     type: RECEIVE_POSTS,
     isFetch:false,
     errorMsg:message
  }
}


// Asynchronous request action, integrating the 3 basic actions above
function getAmount(){
    retrun (dispath)=>{
    // First dispatch: updates the state of the application to notify the API that a request has been made
    dispatch(requestPosts())
    // Asynchronous requests to the back-end interface
        return fetchAmount().then(
             data=>dispath(receviePostOnSuccess(data)),
             error=> dispatch(receviePostOnError('error))
        )
    }
}

This document is a distillation of the most basic use of the presentation, the real react-redux is very deep, if you want to go deeper, find a simple project to start practicing it.

Leave a Reply