useReducer如何实现仅一个布尔值为true无需手动置其他值为false?
方案1:从数据结构层面优化(最推荐)
互斥状态根本不需要维护一组独立布尔值——既然同一时间只能有一个状态为真,直接用单个字段存储当前激活的状态名即可,从根源上消除多布尔值冲突的可能,完全不需要写手动置false的样板代码。
const initialState = { currentStatus: 'loaded' } function reducer (state, action) { switch (action.type) { case 'loadCurrent': return { ...state, currentStatus: 'loadCurrent' } case 'fetchNew': return { ...state, currentStatus: 'fetchNew' } case 'loadPrevHook': return { ...state, currentStatus: 'loadPrevHook' } case 'loadNextHook': return { ...state, currentStatus: 'loadNextHook' } case 'loaded': return { ...state, currentStatus: 'loaded' } } }
使用时直接做等值判断即可,比如判断是否处于loadCurrent状态:state.currentStatus === 'loadCurrent'。这种写法和枚举实现思路一致,是互斥状态的标准设计模式,后续加新状态只需要加一个case,不需要维护一堆冗余的布尔字段赋值。
方案2:兼容原有多布尔值结构
如果受限于现有业务逻辑不能修改状态结构,也可以通过统一的重置逻辑消除样板代码,不需要在每个case里手动给其他字段赋值false:
// 统一维护所有互斥布尔字段的列表 const STATUS_FIELDS = ['loadCurrent', 'fetchNew', 'loadPrevHook', 'loadNextHook', 'loaded'] function reducer (state, action) { // 命中状态切换action时,自动重置所有字段再激活目标状态 if (STATUS_FIELDS.includes(action.type)) { return { ...state, // 先把所有状态字段置为false ...Object.fromEntries(STATUS_FIELDS.map(key => [key, false])), // 激活当前action对应的状态 [action.type]: true } } // 其他非状态切换action走原有逻辑 return state } // 初始状态自动生成,避免手动写一堆false const initialState = { ...Object.fromEntries(STATUS_FIELDS.map(key => [key, false])), loaded: true }
后续新增状态只需要往STATUS_FIELDS数组里加对应字段名即可,不需要重复写冗余的赋值逻辑,也不会出现漏写某个字段导致多true并存的bug。
内容的提问来源于stack exchange,提问作者Zach_is_my_name
相关产品推荐
相关产品推荐

