我正在学习更深层次的redux,而且我在处理更高阶的减速器方面遇到了一些麻烦。
我试图通过一个简单的分页示例来了解它是如何工作的。
注意:以下代码只是nodejs上下文中redux的一个简单示例,没有转换和良好实践,因此,我无法访问spread / destruc运算符,因此我使用它有条不紊地,虽然根本不是一个好习惯,但我知道
所以,让我们想象一下,我有一个可装订的高阶减速器:
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_PAGE
或CHANGE_DISPLAYED
这样的动作时,总是将由两个缩减器arr
处理和list
,我不想要。
我想要创建像CHANGE_DISPLAYED_LIST
和CHANGE_DISPLAYED_ARRAY
这样的新动作,但它会迫使我在可配置的缩减器中管理更多我绝对不想要的动作......我可能会遗漏一些东西很重要。
有什么建议吗?
答案 0 :(得分:2)
实际上你不需要2个减速器。单个高阶减速器可以完成这项工作。
我们可以将类型传递给父包装器并从中返回一个函数。这会在您的州创建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
}
}
现在,按以下方式调用reducer
const indexReducer = combineReducers({
"arrayType": wrapper("array"),
"listType" : wrapper("list")
})
有关详细信息,您可以查看是否重复使用reducer逻辑here。
如果您遇到任何问题,请告诉我。