我在多个页面上都有复选框过滤器,并希望它们在商店的不同部分保持独立。创建非常具体的操作类型(例如TOGGLE_CHECKBOX_SEARCHPAGE_BODYTYPE
)会感觉不对,因为它需要针对每个页面和每个过滤器类型的特定reducer或在一个大型reducer中进行大量检查。
所以我认为行动应该是这样的:
{
type: 'TOGGLE_CHECKBOX',
page: 'search',
filterName: 'bodyType',
payload: 'xxxl'
}
然后我可以写函数返回约束的reducer:
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似乎具有类似的用途,在某些情况下,可能不清楚应该是什么类型。 对于这类问题,你有更明确的解决方案吗?
答案 0 :(得分:2)
创建非常具体的操作类型并没有错,因为操作非常具体。你在你的例子中做了完全相同的事情,它看起来有点复杂并且更难测试(并且它不遵循强烈推荐的FSA标准)。我通常将我的动作类型命名为:
export const SEARCH = {
BODYTYPE: {
TOGGLE: 'SEARCH.BODYTYPE.TOGGLE'
}
}
然后用作:SEARCH.BODYTYPE.TOGGLE
或types.SEARCH.BODYTYPE.TOGGLE
,具体取决于您导入的方式。
您可以根据前缀创建Reducer,而不是使用约束函数,例如:
createCheckboxReducer(prefix) {
return function(state, action) {
switch(action.type) {
case `${prefix}.TOGGLE`:
//do something
return state;
}
}
}
// somewhere else
createCheckboxReducer('SEARCH.BODYTYPE')
几乎相同,但这绝对是我书中的犹太人。旁注:如果我的动作类型嵌套得比这个示例更深,那通常表明它是时候重构并将其分解成更小的模块。
注意:这是所有未经测试的代码