2017-04-05 46 views
0

我正在学习更深入的减速机,并且我在处理更高阶的减速机时遇到了一些麻烦。高阶减速机应用于多个减速机

我想通过一个简单的分页示例来了解它是如何工作的。

注意:下面的代码只是nodejs上下文中redux的一个简单示例,没有转译和良好实践,因此我无法访问spread/destruc运算符,因此我正在使用它,同时这不是一个很好的做法,在所有的,我知道

所以,让我们想象一下,我有一个paginable高阶减速机:

const paginable = (reducer, options) => { 
    const PAGE_OFFSET = options.limit; 
    const ATTRIBUTE_TO_SLICE = options.attr; 
    const initialState = { 
     all: reducer(undefined, {}), 
     displayed: [], 
     limit: PAGE_OFFSET, 
     currentPage: 1 
    }; 

    const _actionHandler = { 
     'CHANGE_PAGE': (state, newPage) => ({all: state.all, displayed: state.displayed, currentPage: newPage, limit: PAGE_OFFSET}), 
     'CHANGE_DISPLAYED': state => ({ 
      all: state.all, currentPage: state.currentPage, limit: PAGE_OFFSET, 
      displayed: state.all[ATTRIBUTE_TO_SLICE].slice((state.currentPage - 1) * PAGE_OFFSET, 
       state.currentPage * PAGE_OFFSET) 
     }) 
    }; 

    return (state = initialState, action) => { 
     const handler = _actionHandler[action.type]; 
     if (handler) { 
      return handler(state, action.payload); 
     } 
     const newAll = reducer(state.all, action); 
     state.all = newAll; 
     return state; 
    }; 
}; 

module.exports = paginable; 

那我想申请这两个减速:

const _actionHandler = { 
    'ADD': (state, item) => ({list: [...state.list, item]}) 
}; 

const initialState = { 
    list: ['a', 'b', 'c', 'd', 'e'] 
}; 

const listReducer = (state = initialState, action) => { 
    const handler = _actionHandler[action.type]; 
    return handler ? handler(state, action.payload) : state; 
}; 

module.exports = listReducer; 

const initialState = { 
    arr: ['z', 'x', 'y', 'b', 'b', 'c', 'd'] 
}; 

const arrayReducer = (state = initialState) => { 
    return state; 
}; 

module.exports = arrayReducer; 

创建我的商店如下:

const redux = require('redux'); 
const listReducer = require('./reducer/list'); 
const arrayReducer = require('./reducer/arrayOfX'); 
const paginable = require('./reducer/paginable'); 

const reducers = redux.combineReducers({ 
    list: paginable(listReducer, {limit: 2, attr: 'list'}), 
    arr: paginable(arrayReducer, {limit: 3, attr: 'arr'}) 
}); 

const store = redux.createStore(reducers); 

我现在的问题是,每一次我将派遣像CHANGE_PAGECHANGE_DISPLAYED一个动作,它总是将由两个减速器arrlist处理,这是我不想要的。

我想要创建像CHANGE_DISPLAYED_LISTCHANGE_DISPLAYED_ARRAY这样的新动作,但它会迫使我在可分页缩减器中管理更多动作,我绝对不想......我可能会丢失重要的东西。

有什么建议吗?

回答

2

你实际上不需要2个reducer。单个高阶减速机可以完成这项工作。

我们可以将该类型传递给父包装并从中返回一个函数。这会在您的状态中创建2个条目。

所以,让我们先创建高阶减速: -

const initialState = { 
    all: {}, 
    displayed: [], 
    limit: PAGE_OFFSET, 
    currentPage: 1 
}; 


export default function wrapper(type) { 
    return function(state=initialState,action) { 
    //using es6 literals to concatenate the string 
    case `CHANGE_DISPLAYED_${type}`: 
     // update your state 
    case `CHANGE_PAGE_${type}`: 
     // update your state 
    } 
} 

现在,调用减速器在下列方式

const indexReducer = combineReducers({ 
    "arrayType": wrapper("array"), 
    "listType" : wrapper("list") 
    }) 

欲了解更多信息,你可以检查出重用减速逻辑here

让我知道你是否面临任何问题。