Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make AJAX request in redux

For all I know, I have to write request in action create. How to use a promise in action for submitting a request? I am getting data in action. Then new state is created in reducer. Bind action and reducer in connect. But I don't know how to use promise for request.

Action

import $ from 'jquery'; export const GET_BOOK = 'GET_BOOK';  export default function getBook() {   return {     type: GET_BOOK,     data: $.ajax({       method: "GET",       url: "/api/data",       dataType: "json"     }).success(function(data){       return data;     })   }; } 

Reducer

import {GET_BOOK} from '../actions/books';  const booksReducer = (state = initialState, action) => {   switch (action.type) {     case GET_BOOK:       return state;     default:       return state;   } };  export default booksReducer; 

Container How display data in container?

import React, { Component, PropTypes } from 'react'; import { connect } from 'react-redux'; import getBook  from '../actions/books'; import Radium from 'radium'; import {Link} from 'react-router';  function mapStateToProps(state) {   return {     books: state.data.books,   }; }  function mapDispatchToProps(dispatch) {   return {     getBooks: () => dispatch(getBook()),   }; }  @Radium @connect(mapStateToProps, mapDispatchToProps) class booksPage extends Component {   static propTypes = {     getBooks: PropTypes.func.isRequired,     books: PropTypes.array.isRequired,   };    render() {     const {books} = this.props;     return (       <div>         <Link to={`/authors`}><MUIButton style="flat">All Authors</MUIButton></Link>         <ul>           {books.map((book, index) =>             <li key={index}>               <Link to={`/book/${book.name}`}><MUIButton style="flat"><div class="mui--text-black mui--text-display4">                 "{book.name}"</div></MUIButton></Link>               <Link to={`/author/${book.author}`}><MUIButton style="flat"><div class="mui--text-black mui--text-display4">                 {book.author}</div></MUIButton></Link>             </li>           )}         </ul>       </div>     );   } }  export default booksPage; 
like image 487
Disa Skolzin Avatar asked Nov 24 '15 10:11

Disa Skolzin


People also ask

Is AJAX request GET or POST?

GET is basically used for just getting (retrieving) some data from the server. Note: The GET method may return cached data. POST can also be used to get some data from the server. However, the POST method NEVER caches data, and is often used to send data along with the request.

How do you send AJAX request every 5 seconds?

Use just setTimeout(executeQuery, 5000); instead of setTimeout('executeQuery()', 5000); - it's shorter and faster.


2 Answers

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 }; } 
like image 51
Jens Avatar answered Oct 30 '22 12:10

Jens


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.
like image 35
Kiddo Avatar answered Oct 30 '22 11:10

Kiddo