[英]React redux multiple requests in one action creator
我想連續以瀑布式方式提出2個要求。 我想先請求一個特定的神奇寶貝,然后根據返回的obj的有效負載類型,請求更多信息。 我認為最好將其分離給幾個動作創建者,但是fetchPokemon
以另一個fetch結尾很奇怪。 這是最佳做法嗎?
export const fetchPokemon = function (pokemonName) {
return function (dispatch) {
dispatch(requestPokemon(pokemonName))
const requestURL = `http://pokeapi.co/api/v2/pokemon/${pokemonName}/`
return $.ajax({
url: requestURL,
}).done(function (data) {
dispatch(receivePokemon(data))
fetchPokeTypeInfo(data.types[0].type.url)
})
}
}
...
export const fetchPokemonTypeInfo = function (url) {
return function (dispatch) {
dispatch(requestPokemonTypeInfo(url))
return $.ajax({
url: url,
}).done(function (data) {
dispatch(receivePokemonTypeInfo(data))
})
}
}
我認為將這兩者分開並沒有什么特別的錯誤。 我要問的一個問題是:“我會直接而不是從fetchPokemon()調用fetchPokemonTypeInfo()嗎?”。 如果沒有,那么我將從第一個.done()函數返回第二個.ajax調用。 如果第一個調用始終是dep,則如果它們只是嵌套,則似乎更容易推斷正在發生的情況。 另外,如果確實希望將它們分開,則需要將調度功能以及url傳遞給第二個函數,否則在fetchPokemonTypeInfo()中未定義調度。
更新:
您可以像這樣將第二個呼叫嵌套在第一個呼叫中:
export const fetchPokemon = function (pokemonName) {
return function (dispatch) {
dispatch(requestPokemon(pokemonName));
const requestURL = `http://pokeapi.co/api/v2/pokemon/${pokemonName}/`;
return $.ajax({
url: requestURL,
}).done(function (data) {
dispatch(receivePokemon(data));
dispatch(requestPokemonTypeInfo(data.types[0].type.url));
return $.ajax({
url: data.types[0].type.url,
}).done(function (data) {
dispatch(receivePokemonTypeInfo(data));
});
});
}
}
有一種方法可以提供干凈且可預測的解決方案。
如果您使用的是redux,則可以利用中間件進行API調用。 此外,在中間件中,您可以擴展其功能,方法是允許接受多個請求(可能在數組中),並在返回成功Promise之前完全解決它們。
檢查此鏈接以供參考: https : //github.com/reactjs/redux/blob/master/examples/real-world/middleware/api.js
這是一個功能性的中間件,但是您必須擴展它以支持多個請求:)祝您好運!
使用redux-saga https://github.com/yelouafi/redux-saga
注意:以下代碼只是一個概念,您需要根據需要進行調整。
function* fetchPokemon(action) {
try {
//fetch1
const pokemon = yield call(Api.fetchPokemon, action.payload.pokemonId);
//this action will execute only after fetch1 is successful
yield put({type: "FETCH_POKEMON_SUCCEEDED", payload: pokemon});
//fetch2
const pokemonInfo = yield call(Api.fetchPokemonInfo, types[0].type.url)
// execute after fetch2 is successful
yield put({type: "FETCH_POKEMON_INFO_SUCCEEDED", payload: pokemonInfo})
} catch (e) {
yield put({type: "FETCH_FAILED", message: e.message});
}
}
// wait for an action and fire a saga
function* watchFetchPokemonRequest() {
yield* take("FETCH_POKEMON_REQUESTED", fetchPokemon);
}
Sagas使用生成器,可以“同步”異步代碼。 這樣,您就無需處理promise等中的回調。這是描述應用程序副作用的一種好方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.