React中如何阻止兄弟组件发生不必要的重新渲染?
问题原因
React.memo 默认对组件props做浅比较判断是否需要重渲染,原代码存在两个导致CompA不必要重渲染的问题:
- 你将useState返回的数组整体作为
Visprop传给两个组件,每次状态更新时这个数组都是全新的引用,即使数组内的更新函数是React保证稳定不会变化的,浅比较也会判定props发生变更,触发CompA重渲染。 - CompA 实际不需要读取显隐状态值,你传递了它用不到的状态,属于多余的prop依赖。
解决方法
拆分props按需传递,避免给组件传不必要的依赖:
- 解构useState的返回值,单独拿到状态值和更新函数,React 保证 useState 返回的更新函数引用永远稳定不会变
- CompA 只接收更新函数作为prop,状态修改用函数式更新实现,不需要依赖外部的当前状态值
- CompB 只接收显隐状态值作为prop,用来控制自身显隐
修改后完整代码
const CompA = React.memo(({setVis})=>{ console.log('Rendered CompA'); return(<Pressable onPress={()=>{setVis(prev => !prev)}} style={...}></Pressable>); }) const CompB = React.memo(({isVis})=>{ console.log('Rendered CompB'); return(<>{isVis && (<View style={...}></View>)}</>); }) export default function App() { const [isVis, setVis] = useState(true); return (<View style={styles.body}> <CompA setVis={setVis}/> <CompB isVis={isVis} /> </View>); }
补充说明
如果你确实有需要传递包含状态和更新函数的数组给组件,也可以给React.memo传入第二个参数自定义比较逻辑,跳过不需要对比的prop项,但这种方式不如拆分props的方案直观易维护,非必要不推荐使用。
内容的提问来源于stack exchange,提问作者user15573857
相关产品推荐
相关产品推荐

