Redux Sagas递归不起作用

时间:2017-03-17 02:27:26

标签: redux redux-saga

我想按项目id找到一个项目及其子项目,我写下面的代码,但是fetchSubItems()总是不起作用,抛出异常'TypeError:无法读取属性'root'的undefined',任何人都可以帮帮我?

export function *fetchItem(api, id){
  const item = yield call (api.getItem, id)
  yield put(Actions.addItem(item))
  yield call(fetchSubItems, item)
  yield put(Actions.success())
}

export function *fetchSubItems(api, item){
  if(item.children){
    const children = yield item.children.map((id)=>{
      return call(api.getItem, id)
    })
    yield put(Actions.addItems(children))

    // the following lines throws 'TypeError: Cannot read property 'root' of undefined'
    yield children.map((child)=>{
      call(fetchSubItems, api, child)
    })
  }
}

1 个答案:

答案 0 :(得分:1)

上次调用似乎缺少return语句。工作示例:

import Promise from 'bluebird';
import { delay } from 'redux-saga';
import { call } from 'redux-saga/effects';

import {
  reducer
} from '../reducers/counter';
import { logger } from '../utils';

const name = '19/Tree_Traversal';
const log = logger(name);

const delayTime = 10;

const tree = {
  1: {children: [2, 3]},
  2: {children: [4, 5, 6]},
  3: {children: []},
  4: {children: []},
  5: {children: []},
  6: {children: [7]},
  7: {children: []}
};

const api = {
  getItem(id) {
    log(`getItem(${id})`);
    return delay(delayTime, tree[id]);
  }
};

export function *fetchItem(/*api, */id = 1) {
  const item = yield call(api.getItem, id);
  // yield put(Actions.addItem(item))
  yield call(fetchSubItems, /*api, */item);
  // yield put(Actions.success())
}

export function *fetchSubItems(/*api, */item) {
  if (item.children) {
    const children = yield item.children.map((id) => {
      return call(api.getItem, id);
    });
    // yield put(Actions.addItems(children))

    yield children.map((child) => {
      return call(fetchSubItems, child); // <=== added `return`
    });
  }
}

export default  {
  name,
  saga: fetchItem,
  reducer: reducer,
  useThunk: !true,
  execute(store) {
    return Promise.delay(8 * delayTime)
    .then(() => this);
  }
};

返回以下日志:

   00000000: [counter reducer] action Object {type: "@@redux/INIT"}
   00000003: [Runner] ---------- running example 19/Tree_Traversal
   00000004: [Runner] store initial state 0
   00000008: [19/Tree_Traversal] getItem(1)
 * 00000060: [19/Tree_Traversal] getItem(2)
   00000061: [19/Tree_Traversal] getItem(3)
 * 00000074: [19/Tree_Traversal] getItem(4)
   00000074: [19/Tree_Traversal] getItem(5)
   00000075: [19/Tree_Traversal] getItem(6)
 * 00000088: [19/Tree_Traversal] getItem(7)
   00000091: [Runner] store final state 0
   00000092: [Runner] ---------- example 19/Tree_Traversal is done