How to make AJAX request in redux
Since you are already using redux you can apply redux-thunk
middleware which allows you to define async actions.
Installation & usage: Redux-thunk
export function fetchBook(id) { return dispatch => { dispatch(setLoadingBookState()); // Show a loading spinner fetch(`/book/${id}`, (response) => { dispatch(doneFetchingBook()); // Hide loading spinner if(response.status == 200){ dispatch(setBook(response.json)); // Use a normal function to set the received state }else { dispatch(someError) } }) }}function setBook(data) { return { type: 'SET_BOOK', data: data };}
You should use Async Actions described in Redux Documentation
Here an example of reducer for async action.
const booksReducer = (state = {}, action) => { switch (action.type) { case 'RESOLVED_GET_BOOK': return action.data; default: return state; }};export default booksReducer;
and then you create your Async Action.
export const getBook() { return fetch('/api/data') .then(response => response.json()) .then(json => dispatch(resolvedGetBook(json)))}export const resolvedGetBook(data) { return { type: 'RESOLVED_GET_BOOK', data: data }}
Several Notes:
- We could return Promise (instead of Object) in action by using redux-thunk middleware.
- Don't use jQuery ajax library. Use other library specifically for doing that (e.g. fetch()). I use axios http client.
- Remember, in redux you only use pure function in reducer. Don't make ajax call inside reducer.
- Read the complete guide from redux docs.
You should be able to use dispatch
inside the callback (if you pass it as an argument):
export default function getBook(dispatch) { $.ajax({ method: "GET", url: "/api/data", dataType: "json" }).success(function(data){ return dispatch({type:'GET_BOOK', data: data}); });}
Then, pass dispatch
to the action:
function mapDispatchToProps(dispatch) { return { getBooks: () => getBook(dispatch), };}
Now, you should have access to the action.data
property in the reducer:
const booksReducer = (state = initialState, action) => { switch (action.type) { case GET_BOOK: //action.data <--- here return state; default: return state; }};