我不明白为什么state.startSlide永远不会更新为1,2,3或4,始终为0
import React, { useState, useEffect } from "react";
import image1 from "../images/carousel/screen-1.png";
import image2 from "../images/carousel/screen-2.png";
import image3 from "../images/carousel/screen-3.png";
import image4 from "../images/carousel/screen-4.png";
import image5 from "../images/carousel/screen-5.png";
const Carousel: React.FC = () => {
interface StateInterface {
showImage: any;
startSlide: number;
}
const [state, setState] = useState<StateInterface>({
showImage: image1,
startSlide: 0
});
useEffect(() => {
const images = [image1, image2, image3, image4, image5];
if (state.startSlide === 0) {
setInterval(function() {
let currentIndex = state.startSlide;
console.log(state.startSlide) // <== always logs 0
console.log(currentIndex) // <== always logs 0
if (state.startSlide < 5) currentIndex++;
else currentIndex = 1;
console.log(state.startSlide) // <== always logs 0
console.log(currentIndex) // <== always logs 1
setState({
showImage: images[currentIndex],
startSlide: currentIndex,
});
console.log(state.startSlide) // <== always logs 0
console.log(currentIndex) // <== always logs 1
}, 3000);
}
}, [state, setState]);
return (
<div className="carousel">
<p>{state.startSlide}</p> // <== Shows 0 then shows 1 but never 2,3,4
<img src={state.showImage}></img>
</div>
);
};
export { Carousel };
答案 0 :(得分:1)
您的代码存在问题,是您尝试直接更改状态:state.startSlide
。但是,永远不要直接更改状态,请始终调用set函数。直接改变状态会导致奇怪的错误,以及难以优化的组件。这是您应该做的:
import React, { useState, useEffect } from "react";
import image1 from "../images/carousel/screen-1.png";
import image2 from "../images/carousel/screen-2.png";
import image3 from "../images/carousel/screen-3.png";
import image4 from "../images/carousel/screen-4.png";
import image5 from "../images/carousel/screen-5.png";
const Carousel: React.FC = () => {
const [showImage, setShowImage] = useState('')
const [startSlide, setStartSlide] = useState(0)
useEffect(() => {
const images = [image1, image2, image3, image4, image5];
if (startSlide === 0) {
setInterval(function () {
console.log(startSlide)
if (startSlide < 5) {
setStartSlide(startSlide => startSlide++)
}
else setStartSlide(1)
setShowImage(images[startSlide])
console.log(startSlide)
}, 3000);
}
}, [startSlide]);
return (
<div className="carousel">
<p>{startSlide}</p>
<img src={showImage}></img>
</div>
);
};
export { Carousel };
答案 1 :(得分:0)
您必须删除if (state.startSlide === 0) {}
,并在startSlide
处增加< 4
。
工作演示:
const { useState, useEffect } = React;
const images = ['image1', 'image2', 'image3', 'image4', 'image5'];
const Carousel: React.FC = () => {
const [state, setState] = useState({
showImage: 'image1',
startSlide: 0
});
useEffect(() => {
const interval = setInterval(function() {
setState(({ startSlide: prevStartSlide }) => {
console.log(prevStartSlide);
let currentIndex = prevStartSlide;
if (currentIndex < 4) currentIndex++;
else currentIndex = 0;
return { showImage: images[currentIndex],
startSlide: currentIndex };
});
}, 3000);
return () => clearInterval(interval);
}, []);
return (
<div className="carousel">
<p>{state.startSlide}</p>
{state.showImage}
</div>
);
};
ReactDOM.render(<Carousel />, document.getElementsByTagName('body')[0]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.10.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.10.2/umd/react-dom.production.min.js"></script>
但是请注意,这并不是最好的方法,更多信息:Making setInterval Declarative with React Hooks
答案 2 :(得分:-1)
我认为您可以在这种情况下使用setInterval,这是一小段代码,可以帮助您实现这一目标。
如果您需要更多帮助,请发表评论。
希望它可以解决您的问题
useEffect(() => {
const interval = setInterval(() => {
yourOperations()
}, 3000);
return () => clearInterval(interval);
});