更新 useState 时 React JS 更新 类
React JS update classes when useState is updated
我正在尝试在 React 中制作轮播滑块。现在我正在检查状态,如果状态为 2,例如添加顺风 class -left-1/3。现在一切正常。但在它添加第一个开关盒之前,我只需要点击两次。有谁知道在 stae 更新时是否有办法(可能使用 useEffect)更新或重新加载?
const Hero = () => {
const [sliderIndex, setSliderIndex] = useState(1);
const [sliderClass, setSliderClass] = useState("-left-0");
console.log(sliderIndex);
const nextSlide = () => {
setSliderIndex(sliderIndex + 1);
console.log("onclick", sliderIndex);
switch (sliderIndex) {
case 1:
setSliderClass("-left-0");
break;
case 2:
setSliderClass(`-left-1/${dataSlider.length}`);
break;
case 3:
setSliderClass(`-left-2/${dataSlider.length}`);
break;
}
if (sliderIndex >= dataSlider.length) {
setSliderIndex(1);
}
};
const prevSlide = () => {
console.log("onclick", sliderIndex);
setSliderIndex(sliderIndex - 1);
switch (sliderIndex) {
case 1:
setSliderClass("-left-0");
break;
case 2:
setSliderClass(`-left-1/${dataSlider.length}`);
break;
case 3:
setSliderClass(`-left-2/${dataSlider.length}`);
break;
}
if (sliderIndex < 2) {
setSliderIndex(3);
}
};
useEffect(() => {
console.log("change");
}, [sliderIndex]);
return (
<header className=" w-screen h-[90vh] relative ">
<div className="flex w-[300%] h-full">
{dataSlider.map((obj, index) => {
return (
<>
<div
className={`${sliderClass} transition-all duration-700 relative w-full h-full`}
>
<img
// layout="fill"
// objectFit="cover"
src={`/sliderImg${index + 1}.jpg`}
alt={obj.aboutImg}
className={` object-cover transition-all duration-1000 h-full w-full`}
/>
<div className="absolute left-4 md:left-20 bottom-8">
<h3 className="text-h2 text-primary font-[magilio] leading-none">
{obj.title}
</h3>
<p className="text-white w-[70%] mb-4">{obj.text}</p>
<Link href={obj.btnHref}>
<button className=" px-8 py-4 text-white rounded active:scale-[0.98] hover:scale-[1.02] transition-transform bg-primary ">
{obj.btnText}
</button>
</Link>
</div>
</div>
</>
);
})}
<button
onClick={prevSlide}
className="absolute md:pl-[18px] pl-[9px] rounded md:w-12 md:h-12 w-8 h-8 z-10 active:scale-[0.98] hover:scale-[1.02] transition-transform cursor-pointer top-0 bottom-0 left-0 mt-auto mb-auto ml-4 md:ml-20 bg-white"
>
<svg
width="10"
height="19"
viewBox="0 0 10 19"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<rect
width="12.368"
height="1.76686"
transform="matrix(0.707425 0.706788 -0.707425 0.706788 1.25 8.18359)"
fill="#111731"
/>
<rect
width="12.368"
height="1.76686"
transform="matrix(-0.707425 0.706788 -0.707425 -0.706788 10 1.92017)"
fill="#111731"
/>
</svg>
</button>
<button
onClick={nextSlide}
className="absolute md:pl-[18px] rotate-180 pl-[9px] rounded md:w-12 md:h-12 w-8 h-8 z-10 active:scale-[0.98] hover:scale-[1.02] transition-transfom cursor-pointer top-0 bottom-0 right-0 mt-auto mb-auto mr-4 md:mr-20 bg-white"
>
<svg
width="10"
height="19"
viewBox="0 0 10 19"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<rect
width="12.368"
height="1.76686"
transform="matrix(0.707425 0.706788 -0.707425 0.706788 1.25 8.18359)"
fill="#111731"
/>
<rect
width="12.368"
height="1.76686"
transform="matrix(-0.707425 0.706788 -0.707425 -0.706788 10 1.92017)"
fill="#111731"
/>
</svg>
</button>
</div>
</header>
);
};
export default Hero;```
@yainspan is correct in his comment。用一些代码来解释:
尽量避免调用setState
willy-nilly。我在这个版本的 prevSlide()
:
中删除了一个不必要的调用
const prevSlide = () => {
console.log("onclick", sliderIndex);
let tempIndex = sliderIndex -1;
if (tempIndex < 2) {
setSliderIndex(3);
}else{
setSliderIndex(tempIndex);
}
};
我还删除了 switch 语句,因为正如 yainspan 所建议的,您可以只使用 sliderIndex 来确定要添加的内容 class(您必须在此处扩展简化版本,但希望逻辑很清楚):
<div
className={`${sliderIndex === 0 ? '-left-0' : sliderIndex === 1 ? '-left-1' : sliderIndex === 2 ? '-left-2' : '' }transition-all duration-700 relative w-full h-full`}
>
我正在尝试在 React 中制作轮播滑块。现在我正在检查状态,如果状态为 2,例如添加顺风 class -left-1/3。现在一切正常。但在它添加第一个开关盒之前,我只需要点击两次。有谁知道在 stae 更新时是否有办法(可能使用 useEffect)更新或重新加载?
const Hero = () => {
const [sliderIndex, setSliderIndex] = useState(1);
const [sliderClass, setSliderClass] = useState("-left-0");
console.log(sliderIndex);
const nextSlide = () => {
setSliderIndex(sliderIndex + 1);
console.log("onclick", sliderIndex);
switch (sliderIndex) {
case 1:
setSliderClass("-left-0");
break;
case 2:
setSliderClass(`-left-1/${dataSlider.length}`);
break;
case 3:
setSliderClass(`-left-2/${dataSlider.length}`);
break;
}
if (sliderIndex >= dataSlider.length) {
setSliderIndex(1);
}
};
const prevSlide = () => {
console.log("onclick", sliderIndex);
setSliderIndex(sliderIndex - 1);
switch (sliderIndex) {
case 1:
setSliderClass("-left-0");
break;
case 2:
setSliderClass(`-left-1/${dataSlider.length}`);
break;
case 3:
setSliderClass(`-left-2/${dataSlider.length}`);
break;
}
if (sliderIndex < 2) {
setSliderIndex(3);
}
};
useEffect(() => {
console.log("change");
}, [sliderIndex]);
return (
<header className=" w-screen h-[90vh] relative ">
<div className="flex w-[300%] h-full">
{dataSlider.map((obj, index) => {
return (
<>
<div
className={`${sliderClass} transition-all duration-700 relative w-full h-full`}
>
<img
// layout="fill"
// objectFit="cover"
src={`/sliderImg${index + 1}.jpg`}
alt={obj.aboutImg}
className={` object-cover transition-all duration-1000 h-full w-full`}
/>
<div className="absolute left-4 md:left-20 bottom-8">
<h3 className="text-h2 text-primary font-[magilio] leading-none">
{obj.title}
</h3>
<p className="text-white w-[70%] mb-4">{obj.text}</p>
<Link href={obj.btnHref}>
<button className=" px-8 py-4 text-white rounded active:scale-[0.98] hover:scale-[1.02] transition-transform bg-primary ">
{obj.btnText}
</button>
</Link>
</div>
</div>
</>
);
})}
<button
onClick={prevSlide}
className="absolute md:pl-[18px] pl-[9px] rounded md:w-12 md:h-12 w-8 h-8 z-10 active:scale-[0.98] hover:scale-[1.02] transition-transform cursor-pointer top-0 bottom-0 left-0 mt-auto mb-auto ml-4 md:ml-20 bg-white"
>
<svg
width="10"
height="19"
viewBox="0 0 10 19"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<rect
width="12.368"
height="1.76686"
transform="matrix(0.707425 0.706788 -0.707425 0.706788 1.25 8.18359)"
fill="#111731"
/>
<rect
width="12.368"
height="1.76686"
transform="matrix(-0.707425 0.706788 -0.707425 -0.706788 10 1.92017)"
fill="#111731"
/>
</svg>
</button>
<button
onClick={nextSlide}
className="absolute md:pl-[18px] rotate-180 pl-[9px] rounded md:w-12 md:h-12 w-8 h-8 z-10 active:scale-[0.98] hover:scale-[1.02] transition-transfom cursor-pointer top-0 bottom-0 right-0 mt-auto mb-auto mr-4 md:mr-20 bg-white"
>
<svg
width="10"
height="19"
viewBox="0 0 10 19"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<rect
width="12.368"
height="1.76686"
transform="matrix(0.707425 0.706788 -0.707425 0.706788 1.25 8.18359)"
fill="#111731"
/>
<rect
width="12.368"
height="1.76686"
transform="matrix(-0.707425 0.706788 -0.707425 -0.706788 10 1.92017)"
fill="#111731"
/>
</svg>
</button>
</div>
</header>
);
};
export default Hero;```
@yainspan is correct in his comment。用一些代码来解释:
尽量避免调用setState
willy-nilly。我在这个版本的 prevSlide()
:
const prevSlide = () => {
console.log("onclick", sliderIndex);
let tempIndex = sliderIndex -1;
if (tempIndex < 2) {
setSliderIndex(3);
}else{
setSliderIndex(tempIndex);
}
};
我还删除了 switch 语句,因为正如 yainspan 所建议的,您可以只使用 sliderIndex 来确定要添加的内容 class(您必须在此处扩展简化版本,但希望逻辑很清楚):
<div
className={`${sliderIndex === 0 ? '-left-0' : sliderIndex === 1 ? '-left-1' : sliderIndex === 2 ? '-left-2' : '' }transition-all duration-700 relative w-full h-full`}
>