通过不仅仅是动作类型来约束还原器



我在多个页面上有复选框过滤器,并希望将它们独立于商店的不同部分。创建非常特定的操作类型(例如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.TOGGLEtypes.SEARCH.BODYTYPE.TOGGLE,具体取决于您的导入方式。

而不是该约束函数,您可以基于前缀创建还原器,例如:

createCheckboxReducer(prefix) {
    return function(state, action) {
        switch(action.type) {
            case `${prefix}.TOGGLE`:
                //do something
                return state;
        }
    }
}
// somewhere else
createCheckboxReducer('SEARCH.BODYTYPE')

几乎相同的事情,但这绝对是我的书中的犹太洁食。旁注:如果我的动作类型比这个示例更深,这通常是该重构和将物品分解成较小模块的迹象。

注意:这是所有未经测试的代码

最新更新