我在多个页面上有复选框过滤器,并希望将它们独立于商店的不同部分。创建非常特定的操作类型(例如TOGGLE_CHECKBOX_SEARCHPAGE_BODYTYPE
)感觉不错,因为它需要每个页面,每个过滤器类型或一个大型还原器内的大量检查。所以我认为动作应该看起来像这样:
{
type: 'TOGGLE_CHECKBOX',
page: 'search',
filterName: 'bodyType',
payload: 'xxxl'
}
我可以写入返回约束还原器的功能:
function constrain(constraints, reducer) {
return function(state, action) {
const allConstraintsPass = Object.getOwnPropertyNames(constraints)
.every( propName => action[propName] === constraints[propName])
if ( ! allConstraintsPass ) {
return reducer(state, {}) // possibly never matching {type: NaN}
}
return reducer(state, action)
}
}
并这样使用:
function someReducer(state, action) {
state = state || {}
switch (action.type) {
case 'TOGGLE_CHECKBOX':
return Object.assign({}, state, {[action.payload]: !state[action.payload]})
default:
return state
}
}
const fuelOnSearchPage = constrain({filterName: 'bodyType', page: 'search'}, someReducer)
console.log(fuelOnSearchPage(undefined, {filterName: 'fuelType', page: 'search', type: 'TOGGLE_CHECKBOX', payload: 'xxl'}));
console.log(fuelOnSearchPage(undefined, {filterName: 'bodyType', page: 'search', type: 'TOGGLE_CHECKBOX', payload: 'xs'}));
console.log(fuelOnSearchPage(undefined, {filterName: 'bodyType', page: 'search', type: 'TOGGLE_CHECKBOX', payload: 'xxl'}));
console.log(fuelOnSearchPage(undefined, {filterName: 'fuelType', page: 'search', type: 'OTHER_ACTION', payload: 'xxl'}));
console.log(fuelOnSearchPage(undefined, {type: 'OTHER_ACTION'}));
我不确定这是否是惯用的redux。在这种情况下,filtername和page似乎具有类型类型,在某些情况下,可能不清楚应该是什么类型。您对此类问题有更明确的解决方案吗?
创建非常特定的动作类型并不是错误的,因为动作非常具体。在示例中,您正在做完全相同的事情,它看起来更复杂,并且很难测试(并且强烈建议您遵循FSA标准)。我通常将我的动作类型命名为:
export const SEARCH = {
BODYTYPE: {
TOGGLE: 'SEARCH.BODYTYPE.TOGGLE'
}
}
然后使用为:SEARCH.BODYTYPE.TOGGLE
或types.SEARCH.BODYTYPE.TOGGLE
,具体取决于您的导入方式。
而不是该约束函数,您可以基于前缀创建还原器,例如:
createCheckboxReducer(prefix) {
return function(state, action) {
switch(action.type) {
case `${prefix}.TOGGLE`:
//do something
return state;
}
}
}
// somewhere else
createCheckboxReducer('SEARCH.BODYTYPE')
几乎相同的事情,但这绝对是我的书中的犹太洁食。旁注:如果我的动作类型比这个示例更深,这通常是该重构和将物品分解成较小模块的迹象。
注意:这是所有未经测试的代码