2017-03-17 73 views
0

我想通過item id找到一個item及其子項,然後我編寫下面的代碼,但fetchSubItems()總是不工作,並拋出異常'TypeError:無法讀取屬性'root'未定義',任何人都可以幫助我?Redux Sagas遞歸不工作

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) 
    }) 
    } 
} 

回答

0

看起來在上次調用中缺少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