为何React父组件状态更新后子组件未重新渲染?
React组件状态更新后子组件未回显初始状态的原因
问题重现
悬停Bar组件时count能正常递增,但点击触发reset后,Foo组件的foo状态已经回到初始值,Bar却依然显示递增后的count,没有恢复初始状态。
关键原因
useState初始值仅生效一次:Bar里的const [bar, setBar] = useState({ ...initialBar }),这个初始值只会在Bar第一次挂载的时候被用来设置bar的初始状态。之后不管父组件传的initialBar怎么变,useState都不会再用这个参数去更新bar的状态。- Bar重新渲染但内部状态未更新:点击
reset后,Foo的foo状态更新,会触发Bar重新渲染(因为initialBar这个props变了),但Bar自己的bar状态还是之前递增后的那个值——useState不会因为props变化就自动重置内部状态。 - 渲染分支未切换,Bar未被重新挂载:
reset后foo.isTrue还是true,所以Foo依然渲染Bar组件,没有切换到<span>{foo.count}</span>。Bar没有被卸载再重新挂载,自然不会重新执行useState的初始化逻辑。
问题代码
const Index = () => { return ( <Foo initialFoo={{ isTrue: true, count: 0 }} /> ) } const Foo = ({ initialFoo }) => { const [foo, setFoo] = useState({ ...initialFoo }) const reset = () => { setFoo({ ...initialFoo }) } return ( <> { foo.isTrue ? <Bar initialBar={foo} reset={reset} /> : <span>{foo.count}</span> } </> ) } const Bar = ({ initialBar, reset }) => { const [bar, setBar] = useState({ ...initialBar }) return ( <div onMouseOver={() => setBar({ ...bar, count: bar.count + 1 })} onClick={reset} > <span>{bar.count}</span> </div> ) }
内容的提问来源于stack exchange,提问作者ezrag26
相关产品推荐
相关产品推荐

