为何需为组件设置key属性才能实现正确卸载与重渲染?
问题原因与解决方案
为什么Dvd/Book切换时组件不卸载、共享状态?
React的diff算法判断组件是否需要重建的核心依据是组件类型+key属性。当你在Switchers.Dvd和Switchers.Book之间切换时,渲染的都是同一个SwitcherForm组件,且未给它们设置不同的key,React会默认这是同一个组件实例,只会更新它的props,不会执行卸载和重新挂载的逻辑——这就导致组件内部的状态被保留,出现“共享状态”、不触发卸载/挂载生命周期(比如useEffect的清理与重新执行)的情况。
而切换到Switchers.Furniture时,外层渲染的是全新的div容器,之前的SwitcherForm会被React判定为不再需要,因此会被卸载;新容器里的SwitcherForm是全新实例(你还给它们加了key={item.name}),所以会正常挂载,不会有状态残留问题。
解决方法
给不同类型下的SwitcherForm添加唯一key,让React能区分它们是不同的组件实例:
const Switcher = ({ switcherType }: ISwitcher) => { switch (switcherType) { case Switchers.Dvd: return <SwitcherForm key={Switchers.Dvd} {...SwitchersText[Switchers.Dvd]} /> case Switchers.Book: return <SwitcherForm key={Switchers.Book} {...SwitchersText[Switchers.Book]} /> case Switchers.Furniture: return ( <div className="switcher"> {SwitchersFurniture.map((item) => ( <SwitcherForm key={item.name} {...item} /> ))} <p className="switcher__descr">Please, provide dimensions.</p> </div> ) default: return <></> } }
这样当switcherType在Dvd和Book之间切换时,React会识别到这是两个独立的组件实例,会先卸载之前的SwitcherForm,再挂载新的,组件状态会被重置,生命周期也会正常执行。
内容的提问来源于stack exchange,提问作者Artemis
相关产品推荐
相关产品推荐

