React中setState为何意外传递旧值?嵌套组件状态更新异常
React组件状态更新异常问题解决
问题根源
你将InnerComp定义在Parent组件内部,每次Parent的parentCount状态更新时,Parent会触发重新渲染,此时InnerComp会被重新定义为一个全新的组件。这会导致其内部的Comp组件被卸载后重新挂载,compCount的状态因此每次都会重置为初始值0。
解决方案
方案1:将InnerComp移到Parent组件外部
把InnerComp抽离到Parent外部,通过props传递setParentCount,这样它就不会随Parent的渲染而被重新创建,Comp的状态就能稳定保留。
修改后的Parent组件代码:
import { useState } from 'react'; function Parent() { const [parentCount, setParentCount] = useState(0); return ( <> <h1>Parent</h1> <hr /> <InnerComp setParentCount={setParentCount} /> <p>parent comp count = {parentCount}</p> </> ); } // 移至Parent外部 function InnerComp({ setParentCount }) { return ( <> <h2>necessary inner comp</h2> <hr /> <Comp setParentCount={setParentCount} /> </> ); }
方案2:使用useMemo缓存InnerComp(需保留在Parent内部时)
如果必须将InnerComp留在Parent内部(比如需要访问Parent的其他内部变量),可以用useMemo缓存组件定义,避免每次Parent渲染都重新创建它。依赖数组仅传入稳定的setParentCount即可。
修改后的Parent组件代码:
import { useState, useMemo } from 'react'; function Parent() { const [parentCount, setParentCount] = useState(0); const InnerComp = useMemo(() => { return () => ( <> <h2>necessary inner comp</h2> <hr /> <Comp setParentCount={setParentCount} /> </> ); }, [setParentCount]); return ( <> <h1>Parent</h1> <hr /> <InnerComp /> <p>parent comp count = {parentCount}</p> </> ); }
原理说明
- 方案1通过将
InnerComp抽离到外部,使其脱离Parent的渲染周期,Comp组件能够保持持续挂载状态,状态不会丢失。 - 方案2利用
useMemo的缓存特性,仅在依赖项变化时重新创建InnerComp,而setParentCount作为React的状态更新函数是稳定的,不会随Parent渲染变化,因此Comp组件不会被反复卸载挂载,compCount的更新就能正常生效。
内容的提问来源于stack exchange,提问作者Pratik Dev
相关产品推荐
相关产品推荐

