我正在尝试渲染一个模式,该模式要么以不同图像的轮播打开,要么以单个静态图像打开。我正在使用 useState 来跟踪 useEffect 挂钩中是否满足该条件。
如下所示:
useEffect(() => {
if (isModalOpen) {
if (focusItem?.hasDetail) {
var arr: string[] = focusItem?.detailPicture?.split(";");
arr?.unshift(focusItem?.pictureLnk);
setDetail(arr);
setHasDetail(true);
}
}
}, [isModalOpen, hasDetail]);
我尝试保持布局相同,即相同的高度和条件渲染的组件,它的工作原理是假设默认情况下不包含带有预览图像的轮播。然而,我的目标是让它以相同的速度渲染。我猜我的逻辑已经关闭,并且有更好的方法来有条件地呈现这些差异。
这是我有条件地渲染组件的方式:
<div className="modalCont">
{hasDetail ? (
<div className="carouselModalImgWrap">
<div className="carouselArrwContLeft">
<Left
className={`carouselArrw ${carouselIndex == 0 ? "arrwDisabled" : ""}`}
onClick={arrowDecrement}
/>
</div>
<div className="carouselImgCont">
{detail?.map((url, i) => {
return (
<div
key={url}
className="carouselImgFit"
style={{
translate: `${-100 * carouselIndex}%`,
transition: `300ms translate ease-in-out`,
}}
>
<div style={{ display: "flex" }}>
<img
className={`modalImg ${carouselIndex == i ? "" : "hideModalImg"}`}
key={url}
src={url}
/>
</div>
</div>
);
})}
</div>
<div className={`carouselImgPrvwWrap ${hasDetail ? "hasWrap" : "nowWrap"}`}>
{detail?.map((url, i) => {
return (
<div className={`carouselImgPrvCont ${carouselIndex == i ? "carouselImgPrevActive": ""}`}>
<img key={url} src={url} className="carouselImgPrv"/>
</div>
);
})}
</div>
<div className="carouselArrwContRight">
<Right
className={`carouselArrw ${carouselIndex == detail?.length - 1 ? "arrwDisabled" : ""}`}
onClick={arrowIncrement}
/>
</div>
</div>
) : (
<div className="modalImgWrap">
<div className="modalImgCont">
<img
className="modalImg"
loading="lazy"
src={focusItem && focusItem.pictureLnk}
/>
</div>
<div className={`carouselImgPrvwWrap ${hasDetail ? "hasWrap" : "nowWrap"}`}>
</div>
</div>
)}
我遇到麻烦的地方是:
<div className={`carouselImgPrvwWrap ${hasDetail ? "hasWrap" : "nowWrap"}`}>
{detail?.map((url, i) => {
return (
<div className={`carouselImgPrvCont ${carouselIndex == i ? "carouselImgPrevActive": ""}`}>
<img key={url} src={url} className="carouselImgPrv"/>
</div>
);
})}
区别在于,如果包含细节,则 div 为 50px,否则为 0px。我最初尝试在没有细节的情况下完全省略 div,但结果是一样的。
请让我知道是否有更好的方法,或者我走错了路......
在这种情况下,最好使用
useLayoutEffect
而不是 useEffect
它们之间的主要区别是:
useLayoutEffect
在渲染之前执行,而useEffect
在渲染之后运行。
useLayoutEffect(() => {
if (isModalOpen) {
if (focusItem?.hasDetail) {
var arr: string[] = focusItem?.detailPicture?.split(";");
arr?.unshift(focusItem?.pictureLnk);
setDetail(arr);
setHasDetail(true);
}
}
}, [isModalOpen, hasDetail]);
https://react.dev/reference/react/useLayoutEffect
此答案是根据问题中提供的内容得出的。组件的更多上下文会有所不同。
您可能根本不需要效果。如果效果只负责检测是否
hasDetail
。你可以做这样的事情:
const hasDetail = isModalOpen && focusItem?.hasDetail