如何正确获取active为true的有效值?附状态切换实现代码
核心错误说明
你当前写的代码有3个明显问题,拿不到正确值也没法正常切换状态:
- 误用
map方法:map是用来生成新数组的方法,不适合用来做遍历修改原数据的操作,而且你在遍历里直接给数组本身加active属性的写法完全不符合数据结构逻辑 - 状态突变:直接修改原
activate数组里的active属性属于React里禁止的直接修改状态操作,React识别不到引用变化,就算调用setActivate也不会正常触发页面更新 - 逻辑错误:判断条件没有匹配传入的
id和列表项id的对应关系,只要不满足id && isActive.active的条件,就会给整个activate数组挂载active=true的属性,完全没法对应到具体项的状态
正确实现代码
首先默认你的activate数组存储结构为[{id: 唯一标识, active: 展开状态布尔值, ...其他业务字段}],分两种常见业务场景给实现:
场景1:支持多项目同时展开(点击单项只切换自身的展开/收起状态)
const expand = (id) => { // 生成全新的状态数组,不修改原数据 const updatedActivate = activate.map(item => { // 匹配到当前点击id对应的项,翻转active状态 if (item.id === id) { return { ...item, active: !item.active } } // 其余项保持原有状态不变 return item }) setActivate(updatedActivate) // 获取所有active为true的目标值,直接过滤新数组即可 const allActiveValues = updatedActivate.filter(item => item.active) // 这里的allActiveValues就是你要的所有展开状态的项,后续逻辑直接用这个变量就行 }
场景2:手风琴模式(同一时间最多只能展开一个项,点开新项自动收起其他项)
const expand = (id) => { const updatedActivate = activate.map(item => { return { ...item, // 只有当前点击id匹配的项设为展开,其余全部收起 active: item.id === id } }) setActivate(updatedActivate) // 手风琴模式下最多只有1个active为true的项,直接find就能拿到 const currentActiveValue = updatedActivate.find(item => item.active) }
注意事项
- 所有React状态更新都要遵循不可变数据原则,不要直接修改原状态对象/数组的属性,必须生成新的引用再传给set方法
- 如果需要基于更新后的状态做后续逻辑,直接在新生成的
updatedActivate数组上取值即可,不要等setActivate执行完再去读原activate变量,那时候拿到的还是旧值 - 不要用map做无返回值的遍历操作,纯遍历执行副作用用
forEach,需要返回新数组做状态更新的时候才用map
内容的提问来源于stack exchange,提问作者hassanMiyan
相关产品推荐
相关产品推荐

