Ответ 1
Использование redux-thunk
:
class PostIndex extends React.Component {
componentDidMount() {
const { dispatch } = this.props;
dispatch(getPosts());
}
...
}
function fetchPosts() {
return dispatch => {
fetchPostsAjax()
.then(res => {
dispatch({ type: 'RECEIVE_POSTS', payload: res });
dispatch(fetchPostMeta(res));
})
}
}
function fetchPostMeta(posts) {
return dispatch => {
fetchPostMetaAjax(posts)
.then(res => dispatch({ type: 'RECEIVE_POST_META', payload: res }));
}
}
}
function fetchPostAjax() {
// return a promise, whether from jQuery.ajax or fetch
}
function fetchPostMetaAjax() {
// return a promise
}
Это довольно стандартный вариант использования для redux-thunk
. Вышеприведенный пример удовлетворен тем, как вы задаете этот вопрос, но вы можете сделать это в одном создателе действия, который выглядит здесь: http://redux.js.org/docs/advanced/AsyncActions.html
Разница в том, что в моем примере я отправляю thunk внутри thunk, вместо того, чтобы выполнять вторую задачу непосредственно внутри первого thunk. Таким образом, это эквивалентно этому:
function fetchPosts() {
return dispatch => {
fetchPostsAsync()
.then(res => { // res is posts
dispatch({ type: 'RECEIVE_POSTS', payload: res });
return fetchPostMetaAsync(res);
})
.then(res => { // res is metadata
dispatch({ type: 'RECEIVE_POST_META', payload: res });
})
}
}
Вы не столкнетесь с какими-либо условиями гонки, потому что, когда вы отправляете какое-либо действие, например { type: RECEIVE_POSTS, payload: res }
, оно синхронно и обновления редуктора перед отправкой следующего действия async.