React中使用.map()渲染图片时如何在加载后获取宽高比设置容器类名
问题原因
你当前所有循环渲染的卡片共用同一个ratio状态,每次图片加载完成调用setRatio都会覆盖之前的状态值,最终所有卡片都会使用最后一张加载完成的图片的比例来判断类名。
无 useState 实现方案(推荐)
直接在图片加载完成后操作对应卡片的DOM元素添加类名,无需额外维护状态,性能更好:
export const ImageCard = ({items}) => { const handleImgLoad = (e) => { // 直接从已加载的图片实例取原始宽高 const { naturalWidth, naturalHeight } = e.target; const ratio = naturalWidth / naturalHeight; // 获取当前图片对应的外层卡片容器 const cardWrapper = e.target.closest('.card-item'); if (ratio > 1.75) { cardWrapper.classList.add('wide'); } } return( <> {items?.map((item, i) => ( // 初始默认只加card-item类,加载完成后动态补wide类 <div className="card-item" key={item.id || i}> {item.mainImage && ( <LazyLoadImage alt={item.title} effect="blur" src={item.mainImage} afterLoad={handleImgLoad} /> )} </div> ))} </> ) }
保留状态的实现方案
如果有其他场景需要存储所有图片的比例,可以用对象类型的状态存储每张图片对应的比例:
export const ImageCard = ({items}) => { // 以图片url/唯一id为key,存储对应宽高比 const [ratioMap, setRatioMap] = useState({}); const handleImgLoad = (e, item) => { const { naturalWidth, naturalHeight } = e.target; const ratio = naturalWidth / naturalHeight; setRatioMap(prev => ({ ...prev, [item.mainImage]: ratio })); } return( <> {items?.map((item, i) => { const curRatio = ratioMap[item.mainImage]; const cardClass = curRatio && curRatio > 1.75 ? 'card-item wide' : 'card-item'; return ( <div className={cardClass} key={item.id || i}> {item.mainImage && ( <LazyLoadImage alt={item.title} effect="blur" src={item.mainImage} afterLoad={(e) => handleImgLoad(e, item)} /> )} </div> ) })} </> ) }
内容的提问来源于stack exchange,提问作者Jhig85
相关产品推荐
相关产品推荐

