Answer the question
In order to leave comments, you need to log in
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) => {
})
}
}
};
}
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;
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
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;
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 questionAsk a Question
731 491 924 answers to any question