簡體   English   中英

在一個動作創建者中響應Redux多個請求

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM