如何将 return 的异步值分配给减速器的初始状态?

How to assign return of async value to initial state of reducer?

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

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

./reducers/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 的数据,但无法 return 返回到 ./reducers/loadMore.js

中的 list

你的 createList returns 一个 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是一个Promise。而是用空列表初始化它,并在 component/container

的 ComponentDidMount 方法中分派 loadMore() 操作

我觉得在你的减速器的初始状态下发出 ajax 请求是 anti-pattern。

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

您可以使用加载 bars/spinners 等指示器来向用户指示数据正在返回。此外,您可以检查数组的长度,或者只是对空数组执行 .map,这不会出错。