The purpose of Redux itself, is to hold our application state. One of the great features of Redux is that we can change our state in a well-defined pattern and it's a pattern that we repeat over and over in our applications.
We call an Action Creator, this produces an Action. The Action flows into our Middleware, then our Reducers which then flows into our application State then into React. Then we sit around and wait for the user to initiate some change inside of our application that repeats the process all over again.
This process works fine with any kind of synchronous change. By synchronous I mean that we call an Action Creator which immediately flows into an Action, Middleware and our Reducers.
The vast majority of web applications we build, however, need to fetch data from asynchronous channels. In other words, its more common to call an Action Creator that is fetching data from an API or some asynchronous action and only when that request resolves are we actually ready to create an Action.
Vanilla Redux is not setup to handle this out of the box.
So, how do we handle these asynchronous Action Creators?
This is where Redux-Thunk comes into play. The purpose of Redux-Thunk is to give us direct control over the Dispatch method. The Dispatch method is part of the ReduxStore that contains our application state.
The Dispatch method handles:
Middleware
Reducers
State
When we normally call an Action Creator and it returns an Action, the Action ends up being returned into this Dispatch method. You have been using the Dispatch method behind-the-scenes in vanilla Redux.
So in practice, say you have a file in actions/index.js
:
import axios from 'axios';
export function fetchUsers() {
const request = axios.get('http://somejsondata.com/users');
}
Redux expects us to return an action, but we do not yet have any data. I have to wait for my request to resolve before I have any data to send across to my Dispatch method.
So, lets use Redux-Thunk where all the existing rules for action creators kind of go out the window. Redux expects for us to return an Action which is a plain JavaScript object.
Redux-Thunk enables one other return type, which is a plain JavaScript function.
import axios from 'axios';
export function fetchUsers() {
const request = axios.get('http://somejsondata.com/users');
return () => {
};
}
The first argument is going to be the dispatch
method:
import axios from 'axios';
export function fetchUsers() {
const request = axios.get('http://somejsondata.com/users');
return (dispatch) => {
};
}
If we pass an Action into dispatch
, it's going to be sent off to all our different reducers.
export function fetchUsers() {
const request = axios.get('http://somejsondata.com/users');
return (dispatch) => {
request.then(({data}) => {
dispatch({type: 'FETCH_PROFILES', payload: data})
});
};
}
This is saying, we are going to wait for request to resolve with some amount of data and only when it has will I dispatch an action. In this case, it is going to have type
FETCH_PROFILES
and payload
of data
.