问题描述
我正在使用PrimeReact进度栏,并希望在加载页面时动态更新它。我的代码如下-
const IntroPage = () => {
const [progressBarValue,setProgressBarValue] = useState(0)
useEffect(() => {
setInterval(function() {
let val = progressBarValue;
val += Math.floor(Math.random() * 10) + 5;
if (val >= 100) {
val = 100;
}
setProgressBarValue(val)
},1000);
},[])
return (
<div className='main-container'>
<div></div>
<div className='progress-bar-container'>
<ProgressBar className='progress-bar' value={progressBarValue}></ProgressBar>
</div>
<div></div>
</div>
)
}
由于某种原因,当我加载页面时,进度条不会不断加到100,它会来回移动,我不太确定为什么会这样。因此它将变为8%或10%,然后下降到6%,依此类推。 我认为问题在于,每次设置新状态时,它都不会添加到先前设置的状态之上。任何帮助将不胜感激。
更新:我也尝试过将setInterval放在单独的函数中并调用它,但这也做同样的事情-
useEffect(() => {
loadProgressBar()
}
},[])
function loadProgressBar() {
setInterval(function(){
let val = progressBarValue;
val += Math.floor(Math.random() * 10) + 5;
if (val >= 100) {
val = 100;
clearInterval();
}
setProgressBarValue(val)
},1000);
}
解决方法
这不是在useEffect you can read more here
中使用间隔函数的正确方法正确的方法是这样:
useEffect(() => {
const intervalId = setInterval(() => {
setProgressBarValue((prev) => {
if (prev >= 100) {
clearInterval(intervalId);
return 100;
} else {
return prev + 5;
}
});
},1000);
return () => clearInterval(intervalId);
},[]);
您实现的问题是progressBarValue
在useEffect内部未更新。setInterval
的回调被编译一次,然后每1000毫秒运行一次(函数及其参数的相同值/引用),因为依赖项数组为空。
这意味着它会读取progressBarValue
的初始值,而不会简单读取下一个值,因为它不是useEffect的依赖项。
在我的实现中,setProgressBarValue()
使用回调函数读取状态的前一个值并将其增加。