D
D
DisaPadla2015-11-24 10:04:58
React
DisaPadla, 2015-11-24 10:04:58

Where and how to make an AJAX request in redux?

There was already a question about this, but I did not really manage to figure it out. I need to send a normal get request to get json data from the server. As I understand it, the request is written in the action creator using a promise, but I could not understand how it was named. How is the request done correctly in the redux architecture?
action

import $ from 'jquery';
export const GET_BOOK = 'GET_BOOK';

export default function getBook() {
  return {
    type: GET_BOOK,
    data: {
      promise: () => {
        return new Promise((resolve, reject) => {
          
        })
      }
    }
  };
}


reducer
import {GET_BOOK} from '../actions/books';

const booksReducer = (state = 0, action) => {
  switch (action.type) {
  case GET_BOOK:
    return action.data;
  default:
    return state;
  }
};

export default booksReducer;


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.promise(),
  };
}

function mapDispatchToProps(dispatch) {
  return {
    getBooks: () => dispatch(getBook()),
  };
}

@Radium
@connect(mapStateToProps, mapDispatchToProps)
class booksPage extends Component {
  static propTypes = {
    books: PropTypes.array.isRequired,
  };

  render() {
    const {books} = this.props;
    return (
      <div>
        <p><Link to={`/authors`}>All Authors</Link></p>
        <ul>
          {books.map((book, index) =>
            <li key={index}>
              <p><Link to={`/book/${book.name}`}>{book.name}</Link></p>
              <p><Link to={`/author/${book.author}`}>{book.author}</Link></p>
            </li>
          )}
        </ul>
      </div>
    );
  }
}

export default booksPage;

Answer the question

In order to leave comments, you need to log in

2 answer(s)
N
Nikita Gushchin, 2015-11-24
@iNikNik

To work with promises, you need to use an additional middleware - promise middleware. There are several implementations - you can choose any you like. I use this one and will write about it further.
Yes, that's right. In the action-creator, we make a request, return the action with a promise. Then promiseMiddleware picks it up and instead of one action it dispatches 3 - the action started, the action completed successfully, the action ended with an error. All this happens depending on what state the above promise is in. In other words - "the action has begun" will be dispatched immediately; if the request is successful, "action completed successfully" will be dispatched.
Accordingly, in your reducer you subscribe to these three actions. Example:

// action creator
import fetch from 'isomorphic-fetch';

export default function getBook() {
  // Для запросов чаще всего используется  isomorphic-fetch, который возвращает promise
  const promise = fetch(url, options);
  return {
    types:  [ 'GET_BOOK-BEGIN', 'GET_BOOK-SUCCESS', 'GET_BOOK-FAILURE' ],
    promise,
  };
}

// reducer
import {GET_BOOK} from '../actions/books';

const booksReducer = (state = {}, action) => {
  switch (action.type) {
    case 'GET_BOOK-SUCCESS':
      // При успешном завершении у нас установлено свойство result с ответом сервера
      return action.result;
    case 'GET_BOOK-FAILURE':
      // При неудачном завершении у нас установлено свойство error с описанием ошибки
      doSomethingWithError(action.error); // <--- просто для примера
    default:
      return state;
  }
};

export default booksReducer;

UPD1 By the way: redux has a great example where you can see all this live - https://github.com/rackt/redux/tree/master/example...

M
Maxim, 2016-02-26
@maxfarseer

As it was already written, yes, you need to use thunk-middleware, the code of which, by the way, is very simple!
The bottom line is that you need to check: if your action returns a function, then throw dispatch and getState into it and wait for what happens next, and if your action is a simple object (as intended) - immediately throw it further. This is how middleware works - adding functionality and forwarding execution further.
I have a detailed redux tutorial in Russian, take a look here - https://www.gitbook.com/book/maxfarseer/redux-cour...
Thanks.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question