Since this is an asynchronous action you will want to use middleware in order to handle the dispatching of multiple actions at different times.
Actions creators are synchronous by nature so this is why middleware is necessary in order to dispatch synchronous actions in the future when the response comes back from your request.
In order to get to grips I would recommend you use redux-thunk as is easier to get to grips with than the main alternative redux-promise middleware library.
Redux Thunk Middleware
Redux Thunk middleware allows you to write action creators that return a function instead of an action.
First set up your redux-thunk middleware during your store configuration
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';
const store = createStore(
rootReducer,
applyMiddleware(thunk)
);
Now redux-thunk knows how to handle the dispatching of special thunk actions
A thunk actions is just an action that returns another function that takes dispatch as an argument.
Thunk action creator
function fetchThing(url) {
return (dispatch) => {
/*dispatch more actions*/
}
}
The advantage of this is that our components can dispatch asynchronous actions as if they were synchronous and do not need to be passed the dispatch function and therefore don't need to know about the Redux store.
The redux-thunk middleware knows to intercept our thunk action just after we create it, passing in dispatch so future actions such as a RESPONSE_RECEIVED action will have access to dispatch.
In order to use redux-thunk create an action creator which returns a function that accepts dispatch as an argument as per the above.
Example
function epSearch(query){
// thunk passes dispatch into the function below
// so that future actions will have access to dispatch
return function(dispatch){
// below function needs to return a promise in order for us to call .then
getAsynch(data).then(
result => dispatch({ type: GET_DATA, payload:result }),
error dispatch({ type: REQUEST_ERROR, payload: error })
);
};
}
If the promise is not resolved due to an error than our REQUEST_ERROR action will be dispatched and the payload of the action will be the error we received from the rejected promise
Redux Promise and Alternatives to Redux Thunk
Now there are other ways of controlling your async data flow. However redux-thunk is simple and convenience in my opinion. Redux Promise is a a good alternative to Redux Thunk. The difference here is that redux-promise is middleware that intercepts action creators that return promises instead of thunks.
However strictly speaking you don't need middleware at all in redux for async flow. The advantage of it is the centralisation of data flow in one place that allows your components to be more decoupled as they do not need to be explicitly passed the Redux's store's dispatch method and therefore do not care about how and action is created.
For an in depth discussion on middleware in Redux see this answer by Dan Abramov's to the question of why do we need middleware for async flow in redux,