Thunks are functions wrap expressions in order to delay their evaluation.
This delay is achieved in Redux thunk a when an action is called it returns a function. This function that is returned can then be called at a later time.
Here is an example of a thunk action.
function incrementAsync() {
// the below function is called by Redux Thunk middleware below.
return dispatch => {
setTimeout(() => {
// Yay! Can invoke sync or async actions with `dispatch`
dispatch(increment());
}, 1000);
};
A higher order function is just a function that either returns a function or takes a function as one of its arguments. Because this function returns another function that takes dispatch as an argument this is an example of a higher order function.
The code from the redux thunk middleware resembles this
function createThunkMiddleware() {
return store => next => action => {
if (typeof action === 'function') {
// since action is a function it is a thunk action creator
// so call it with store methods
return action(store.dispatch, store.getState);
}
// action is not a function so redux thunk ignores it
return next(action);
};
}
As soon as our thunk action creator is called it sends the action function through the middleware chain. When it reaches our thunk middleware this action is recognised as a function and therefore called again with the dispatch and getState methods of the store.
Because of this second function call we are now in the scope of the returned function from our thunk action creator. This means that we can now execute asynchronous logic and still have access to the store's getState and dispatch methods. This is why our thunk action creator can be considered a thunk expression. By using a higher order function we can have access to, yet postpone the use of the store's dispatch or getState method to a future time. As seen below, the increment action is called after a one second delay.
function incrementAsync() {
// the below function is called by Redux Thunk middleware below.
return dispatch => {
setTimeout(() => {
// Yay! Can invoke sync or async actions with `dispatch`
dispatch(increment());
}, 1000);
};