React Redux Tutorials - 13 - Redux Thunk Middleware

jh22j9·2020년 10월 14일
0

React Redux Tutorials

목록 보기
13/20

Async action creators


How to use action creators with network request, that is how to make an API call when working with redux ?

We need to install two packages:

Axois

will be used to make get request to an api endpoint.

Redux-thunk

is the standard way to define asynchronous action creators in the application.

The Redux-thunk library is a middleware we will be applying to our redux store.

How to define async action creator using Axios and redux-thunk ?


(1) install two packages

npm install axios redux-thunk

(2) apply the redux thunk middleware to the redux store

const applyMiddleware = redux.applyMiddleware;
const applyMiddleware = redux.applyMiddleware;
const thunkMiddleware = require('redux-thunk').default;

const store = createStore(reducer, applyMiddleware(thunkMiddleware));

(3) import axios

const axios = require('axios');

(4) define the async action creator

Basically an action creator returns an action.

But thunkMiddleware brings the ability for an action creator to return a function instead of an action object.

const fetchUsers = () => {
  // so we can now return a function.
  // this function doesn't have to be pure. so it is allowed to have side effects such as async API calls.
  // this function can also dispatch actions.
  return function(dispatch) {

    // before we fire off the API call, we dispatch fetchUserRequest to set loading to true
    dispatch(fetchUsersRequest()) 

    // get the url endpoint using JSONPlaceholder to make a get request.
    axios.get('https://jsonplaceholder.typicode.com/users')
    .then(response => {

      // response data is the array of users
      const users = response.data.map(user => user.id)

      // dispatch fetchUsersSucess to store the user in our stsate
      dispatch(fetchUsersSuccess(users))
    })
    .catch(error => {

      // error.message is the error description

      // dispatch fetchUsersFailure to display error message.
      dispatch(fetchUsersFailure(error.message));  
    })
  };
};

(5) subscribe to the store

store.subscribe(() => {console.log(store.getState())})

(6) dispatch the async action creator

store.dispatch(fetchUsers());

Summary


Import the redux-thunk middleware and pass it to the createStore function. What this allows is for an action creator to return a function instead of an action object. The function can now perform side effects such as asynchronous tasks. The function also can dispatch regular actions which will be handled by the reducer.

📃 Code


const redux = require('redux'); 
const createStore = redux.createStore; 

const applyMiddleware = redux.applyMiddleware;
const thunkMiddleware = require('redux-thunk').default;

const axios = require('axios');

const initialState = {
  loading: false,
  users: [],
  error: ''
};

const FETCH_USERS_REQUEST = 'FETCH_USERS_REQUEST';
const FETCH_USERS_SUCCESS = 'FETCH_USERS_SUCCESS';
const FETCH_USERS_FAILURE = 'FETCH_USERS_FAILURE';

const fetchUsersRequest = () => {
  return {
    type: FETCH_USERS_REQUEST
  }
};

const fetchUsersSuccess = users => {
  return {
    type: FETCH_USERS_SUCCESS,
    payload: users
  }
};

const fetchUsersFailure = error => {
  return {
    type: FETCH_USERS_FAILURE,
    payload: error
  }
};

const reducer  = (state = initialState, action) => {
  switch(action.type) {
    case FETCH_USERS_REQUEST:
      return {
        ...state,
        loading: true
      }
    case FETCH_USERS_SUCCESS:
      return {
        loading: false,
        users: action.payload,
        error: ''
      }
    case FETCH_USERS_FAILURE:
      return {
        loading: false,
        users: [],
        error: action.payload
      }
  };
};

// define async actions creator
/* an action creator returns an action.
But thunkMiddleware brings the ability for an action creator to return a function instead of an action object. */
const fetchUsers = () => {

  // so we can now return a function.
  // this function doesn't have to be pure. so it is allowed to have side effects such as async API calls.
  // this function can also dispatch actions.
  return function(dispatch) {

    // before we fire off the API call, we dispatch fetchUserRequest to set loading to true
    dispatch(fetchUsersRequest()) 

    // get the url endpoint using JSONPlaceholder to make a get request.
    axios.get('https://jsonplaceholder.typicode.com/users')
    .then(response => {

      // response data is the array of users
      const users = response.data.map(user => user.id)

      // dispatch fetchUsersSucess to store the user in our stsate
      dispatch(fetchUsersSuccess(users))
    })
    .catch(error => {

      // error.message is the error description

      // dispatch fetchUsersFailure to display error message.
      dispatch(fetchUsersFailure(error.message));  
    })
  };
};

const store = createStore(reducer, applyMiddleware(thunkMiddleware));

// subscribe our store 
store.subscribe(() => {console.log(store.getState())})

// dispatch the async action creator
store.dispatch(fetchUsers());

node asyncActions

{ loading: true, users: [], error: '' }
{ loading: false,
  users: [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ],
  error: '' }

0개의 댓글

관련 채용 정보