React在一个操作创建器中redux多个请求



我想连续发出2个请求,有点像瀑布式的方式。我想首先请求一个特定的口袋妖怪,然后基于返回对象的有效载荷类型,我想请求更多信息。我认为最好是将其划分给几个动作创造者,但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))
    })
  }
}

我不认为把这两个人分开有什么特别不对的。我要问的一个问题是:"我会直接调用fetchPokemonTypeInfo(),而不是从fetchPokemon()吗?"如果没有,那么我就返回第一个.done()函数中的第二个.ajax调用。如果第一次调用总是一个深度,那么如果它们只是嵌套,似乎更容易推断出发生了什么。另外,如果你想让它们分开,你需要将分派函数和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调用。此外,在你的中间件中,你可以扩展它的功能,允许接受多个请求(可能在数组中),并在返回成功承诺之前一起解决它们。

查看此链接以供参考: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);
}

saga使用generator,它"使"你的异步代码同步。这样你就不需要在promises等中处理回调。这是一种描述应用程序副作用的好方法。

相关内容

  • 没有找到相关文章

最新更新