You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

createStructuredSelector中选择器使用逻辑OR运算符失效如何解决

问题原因

你之前的写法pending: selectIsPending_1 || selectIsPending_2存在本质错误:||运算符是在选择器初始化定义阶段执行的,不是在每次传入state计算结果阶段执行的。JavaScript中函数本身是真值,因此这段表达式永远只会返回第一个选择器selectIsPending_1,selectIsPending_2从始至终都没有被传入选择器集合,自然永远不会执行,最终pending值只会取selectIsPending_1的返回结果,初始加载后就恒为false。

你目前用的临时方案pending: () => selectIsPending_1(state) || selectIsPending_2(state)虽然能跑通逻辑,但存在两个明显问题:

  • 无参箭头函数依赖闭包捕获外层的state变量,写法不符合reselect选择器的入参规范,容易出现作用域异常
  • 这个匿名函数没有经过reselect记忆化包装,每次state更新都会重复执行计算,完全失去了reselect的性能优化能力
正确写法

推荐使用reselect官方提供的createSelector方法,先将OR逻辑封装为带记忆化能力的独立选择器,再传入createStructuredSelector:

// 组合两个pending状态的判断逻辑,生成带缓存的新选择器
const selectCombinedPending = createSelector(
  [selectIsPending_1, selectIsPending_2],
  (isPending1, isPending2) => isPending1 || isPending2
)

const mapStateToProps = state => ({
  someProp: state.someProp,
  ...createStructuredSelector({
    pending: selectCombinedPending
  })(state)
})

这种写法下,只有当selectIsPending_1或selectIsPending_2的返回值发生变化时,才会重新执行OR逻辑计算pending的值,既保证逻辑正确,也保留了reselect的记忆化性能优势。

如果只是临时快速实现,不想额外拆分选择器,也可以直接给createStructuredSelector传入符合签名的选择器函数(入参为state),但这种写法没有缓存效果,不推荐在生产环境使用:

const mapStateToProps = state => ({
  someProp: state.someProp,
  ...createStructuredSelector({
    pending: (state) => selectIsPending_1(state) || selectIsPending_2(state)
  })(state)
})
注意事项
  • 所有涉及选择器返回值的逻辑运算,都要放在createSelector的结果计算函数内执行,不要直接在选择器定义层对选择器函数本身做逻辑运算
  • createStructuredSelector接收的对象属性值必须是符合(state, ownProps?) => 任意值签名的选择器函数,不要传入依赖闭包捕获变量的无参函数

内容的提问来源于stack exchange,提问作者Anton Karpenko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 01:51:44