React中prop变更后子组件未重新渲染问题如何解决?
问题原因
React 对 useState 管理的状态进行更新时,会通过浅对比判断状态是否发生变更,问题的核心原因是违反了React的不可变数据原则:
- 你在
toggleLight方法中直接将原状态对象activeButtons的引用赋值给变量buttons,直接修改原对象的属性后又将同一个引用的对象传入setActiveButtons,React 对比新旧状态的引用完全一致,就会判定状态没有更新,不会触发父组件重渲染,子组件自然无法接收到更新后的 prop。 - 直接修改原状态对象的写法属于React官方不推荐的错误用法,会导致状态更新不生效、调试困难等问题。
解决方案
遵循不可变数据原则,每次更新状态时传入全新的对象即可,推荐使用函数式更新配合展开运算符实现,同时可以优化为按传入的id动态修改对应按钮的状态,适配两个按钮的切换逻辑:
function toggleLight(type, id) { if(type && id) { setActiveButtons(prevState => ({ // 展开原有状态的所有属性 ...prevState, // 动态修改对应id的状态值,此处为切换逻辑,若需要固定设为true可直接写true [id]: !prevState[id] })) } }
如果是层级更深的复杂对象,也可以先对原状态做深拷贝再修改属性后传入set方法,当前一层对象的场景下展开运算符性能最优。
修改后React会识别到状态引用变化,触发父组件重渲染,子组件的props.active会同步更新,对应的useEffect监听也会正常触发。
补充说明:原有代码中setActiveButtons之后直接打印activeButtons会拿到旧值,这是React状态更新的异步特性导致的,属于正常表现,如果需要拿到更新后的状态,可以在useEffect中监听activeButtons变化后打印。
内容的提问来源于stack exchange,提问作者Jonas
相关产品推荐
相关产品推荐

