React用useState实现div悬停切图时所有图片同步变更如何修复
问题原因
所有div共用了同一个布尔类型的open状态,任意一个div触发setOpen都会修改全局唯一的这个状态,导致所有图片的判断条件同时变更,因此会出现悬停单个div所有图片都切换的问题。
解决方案
这里提供两种常用的实现方式,你可以根据自己的业务场景选择:
方案1:状态存储当前悬停的元素标识
给每个公司块分配唯一的标识,悬停时将对应标识存入状态,渲染时判断当前块的标识与状态存储的标识是否一致,来决定是否切换图片。
代码示例:
// 状态修改为存储当前悬停的元素id const [hoverId, setHoverId] = useState(null); <div className="container-fluid" id="companies"> <div className="row"> <div className="col-md-3 p-0"> <div className="company-block" onMouseOver={() => setHoverId('blockFi')} onMouseOut={() => setHoverId(null)}> <Image src={hoverId === 'blockFi' ? BlockFiBlack : BlockFiWhite}/> </div> </div> <div className="col-md-3 p-0"> <div className="company-block" onMouseOver={() => setHoverId('nerdWallet')} onMouseOut={() => setHoverId(null)}> <Image src={hoverId === 'nerdWallet' ? NerdWalletBlack : NerdWalletWhite}/> </div> </div> <div className="col-md-3 p-0"> <div className="company-block" onMouseOver={() => setHoverId('superRate')} onMouseOut={() => setHoverId(null)}> <Image src={hoverId === 'superRate' ? SuperRateBlack : SuperRateWhite}/> </div> </div> <div className="col-md-3 p-0"> <div className="company-block" onMouseOver={() => setHoverId('xeal')} onMouseOut={() => setHoverId(null)}> <Image src={hoverId === 'xeal' ? XealBlack : XealWhite}/> </div> </div> </div> </div>
方案2:封装独立的子组件(更推荐)
将每个公司块封装为独立的组件,每个组件内部维护自己的悬停状态,组件之间状态互不干扰,同时也符合React组件复用的设计思想。
代码示例:
// 封装独立的公司项组件 const CompanyItem = ({ blackImg, whiteImg }) => { const [isHover, setIsHover] = useState(false); return ( <div className="col-md-3 p-0"> <div className="company-block" onMouseOver={() => setIsHover(true)} onMouseOut={() => setIsHover(false)} > <Image src={isHover ? blackImg : whiteImg}/> </div> </div> ) } // 父组件中直接调用即可 const ParentComponent = () => { return ( <div className="container-fluid" id="companies"> <div className="row"> <CompanyItem blackImg={BlockFiBlack} whiteImg={BlockFiWhite} /> <CompanyItem blackImg={NerdWalletBlack} whiteImg={NerdWalletWhite} /> <CompanyItem blackImg={SuperRateBlack} whiteImg={SuperRateWhite} /> <CompanyItem blackImg={XealBlack} whiteImg={XealWhite} /> </div> </div> ) }
内容的提问来源于stack exchange,提问作者fahad javed
相关产品推荐
相关产品推荐

