As we see on our screens, there are only two actions needed for this app, fetchImages
(for all users or for a specific user) and addImage
:
/*** src/actions/index ***/ import api from '../api'; export function fetchImages(userId = null) { let actionName, actionNameSuccess, actionNameError; if(userId) { actionName = 'FETCH_USER_IMAGES'; actionNameSuccess = 'FETCH_USER_IMAGES_SUCCESS'; actionNameError = 'FETCH_USER_IMAGES_ERROR'; } else { actionName = 'FETCH_IMAGES'; actionNameSuccess = 'FETCH_IMAGES_SUCCESS'; actionNameError = 'ADD_IMAGE_ERROR'; } return dispatch => { dispatch({ type: actionName }); api .fetchImages(userId) .then(images => { dispatch({ type: actionNameSuccess, images }) }) .catch(error => { dispatch({ type: actionNameError, error }); }); }; } export function addImage(data = null) { return dispatch => { dispatch({ type: 'ADD_IMAGE' }); api .addImage() .then(imageSrc => { dispatch({ type: 'ADD_IMAGE_SUCCESS', imageSrc }); }) .catch(error => { dispatch({ type: 'ADD_IMAGE_ERROR', error }); }); }; }
Redux actions are just simple objects describing an event, including its payload. Since we are using redux-thunk
, our action creators will return a function in which the Redux dispatch
function will be called, passing the action. Let's take a closer look at our addImage
action:
export function addImage(data = null) { return dispatch => { dispatch({ type: 'ADD_IMAGE' }); api .addImage() .then(imageSrc => { dispatch({ type: 'ADD_IMAGE_SUCCESS', imageSrc }); }) .catch(error => { dispatch({ type: 'ADD_IMAGE_ERROR', error }); }); }; }
The function we return starts by dispatching an action named ADD_IMAGE
with no payload, as we just want to let Redux know that we are ready to make a network request to upload the image to our backend. Then, we make that request using our api
(we will mock this call later). This request will return a promise, so we can attach .then
and .catch
callbacks to handle the response. If the response is positive (the image was properly uploaded), we will dispatch an ADD_IMAGE_SUCCESS
action passing the URL for the uploaded image. If there is an error, we will dispatch an ADD_IMAGE_ERROR
action covering all the possible states.
Most of the action creators work in a similar way when making network requests in Redux and Thunk. In fact, our action fetchImages
is very similar to addImage
, with one exception: it needs to check if userId
was passed and issued a different set of actions instead, so the reducers can modify the state accordingly. Let's then take a look at the reducers, which will be handling all these actions.
3.129.148.210