React Redux表现得很奇怪

时间:2018-03-31 02:34:07

标签: javascript reactjs redux

下面是我的reducer及其输出。结果非常奇怪。 变量 actions.pokemons :是一个数组,每个元素都是一个对象。它的值被赋值给a并复制到b。 我不明白为什么b是空数组。另外,返回值是一个空数组,状态不是更新?

const pokemons = (state=[], action) => {
    switch(action.type){
        case types.FETCH_POKEMON:
            var a = action.pokemons
            console.log(a)
            var b = [...action.pokemons]
            console.log(b)
            return a;

        default: return [...state];
    }
}

enter image description here

这是我的行动档案:



import * as types from '../constants/index';
import axios from 'axios'; 
export const actFetchPokemonsRequest = () => {
    return dispatch => {
        var result = [];
        for(var i=1; i<3; i++){
            axios({
                method: 'GET',
                url: `https://pokeapi.co/api/v2/pokemon/${i}`,
                data: null
            }).then(res => {
                // console.log(res.data)
                result.push(res.data)
                return dispatch(actFetchPokemon(result))
            }).catch(err => console.log(err))
        }
        return dispatch(actFetchPokemon(result))
    }
}

export const actFetchPokemon = pokemons => {
    return {
        type: types.FETCH_POKEMON,
        pokemons
    }
}
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:3)

正如有人已经提到过,你的异步部分不像你想象的那样工作。这就是发生的事情。

  1. 您实例化一个名为result
  2. 的空数组
  3. 你开始一个for循环,每个循环开始一个Promise,你到达for循环的结尾 任何Promise被解决之前。循环结束非常快,代码转到下一个语句。
  4. 在return语句中,调用传递接收数组的操作的调度。你在for循环之后就到了这里,因为没有一个Promise已经解决了你的result是空的。
  5. 执行此操作的方法如下:

    import * as types from '../constants/index';
    import axios from 'axios'; 
    
    export const actFetchPokemonsRequest = () => {      
        return dispatch => {
          const pokemonRequests = [
            axios({ method: 'GET', url: 'https://pokeapi.co/api/v2/pokemon/0', data: null }),
            axios({ method: 'GET', url: 'https://pokeapi.co/api/v2/pokemon/1', data: null }),
            axios({ method: 'GET', url: 'https://pokeapi.co/api/v2/pokemon/2', data: null }),
          ];
    
          Promise.all(pokemonRequests).then((responses) => {
            const dataArr = responses.map(r => r.data);
    
            dispatch(actFetchPokemon(dataArr));
          });
        }
    }
    
    export const actFetchPokemon = pokemons => {
      return {
        type: types.FETCH_POKEMON,
        pokemons,
      }
    }
    

    在你的减少中,你只需要:

    const pokemons = (state = [], action) => {
      switch(action.type){
        case types.FETCH_POKEMON:
          return [...action.pokemons];
          // Or if you want to simply extend what you currently have
          // return [...state, ...action.pokemons];
        default:
          return state;
      }
    }
    

    要了解有关异步部分的更多详细信息,请注意的是,您将关闭所有axios个请求。但是你想要等待所有人解决,这就是Promise.all派上用场的地方。 Promise.all等待所有Promises解析,然后将每个promise的响应(如果有的话)连接到一个数组中。这是我可以在其上使用.map并实际从每个请求响应中提取data字段的方式。一旦我完成了所有这些,我终于可以发送我的动作,现在传递一个有效的数据数组。有关Promise.all的大量文档,所以我建议你看一下。

    我希望这有助于解决您的问题,如果这对您没有帮助,请告诉我。

    注意:为简单起见,我手动记下了所有请求,但有更好的方法可以动态地执行此操作。