如何将异步值的返回值分配给reducer的初始状态?

时间:2017-02-13 23:30:06

标签: reactjs redux react-redux

完整代码:https://github.com/kenpeter/test_infinite_scroll_1

我有减速机。它有一个名为list的道具。 createList([], 0)调用远程api并获取数据,然后分配给list

./减速器/ loadMore.js

import { MORE_LIST } from "../actions/types";
import { createList } from "../utils/func"; 

const initState = {
  list: createList([], 0) // <--------------------
};

// able to fire
export default function list(state = initState, action = {}) {
  switch(action.type) {

    case MORE_LIST:
      return {
        list: action.list,
      }

    default:
      return state;
  }
}

./ utils的/ func.js

import _ from 'lodash';
import axios from "axios";

// clone the array
export function createList(arr=[],start=0) {
  let apiUrl = "http://www.mangaeden.com/api/list/0?p=0";

  return axios.get(apiUrl).then((obj) => {
    let arr = obj.data.manga; // array of obj

    //console.log("--- start ---");
    //console.log(arr);  

    return arr;        
  });
}  

我与function createList(arr=[],start=0)的问题是 arr包含来自远程api的数据,但无法返回list中的./reducers/loadMore.js

2 个答案:

答案 0 :(得分:4)

我觉得在初始状态下为减速器发出ajax请求是一种反模式。

相反,我只是将初始状态作为一个空数组,然后在您的应用程序启动时或在适当的组件的生命周期中(例如componentWillMount)我会调度一个动作来获取数据。

您可以使用加载条/旋转器等指示器向用户指示数据即将返回。此外,您可以检查数组的长度,或者只在空数组上执行.map,这样就不会出错。

答案 1 :(得分:0)

您的createList返回一个Promise。所以在client/actions/loadMore.js你需要做的事情:

return createList(list, list.length+1).then((tmpList) => {
    dispatch({
      type: MORE_LIST,
      list: tmpList
    });
});

此外,正如patric所述,client/reducers/loadMore.js中的以下代码是异步的,

const initState = {
  list: createList([], 0)
};

这里的initState.list是承诺。而是使用空列表初始化它并在组件/容器的ComponentDidMount方法中调度loadMore()操作