Javascript 在React with Hooks中实现倒计时
我试图用react钩子在屏幕上渲染倒计时,但我不确定渲染它的最佳方式 我知道我应该使用useEffect来比较当前状态和以前的状态,但我认为我做得不对 我会感谢你的帮助 我尝试过几种不同的方法,没有一种是有效的,比如在每次更新时设置状态,但最终都会疯狂地闪烁Javascript 在React with Hooks中实现倒计时,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我试图用react钩子在屏幕上渲染倒计时,但我不确定渲染它的最佳方式 我知道我应该使用useEffect来比较当前状态和以前的状态,但我认为我做得不对 我会感谢你的帮助 我尝试过几种不同的方法,没有一种是有效的,比如在每次更新时设置状态,但最终都会疯狂地闪烁 const Timer = ({ seconds }) => { const [timeLeft, setTimeLeft] = useState(''); const now = Date.now();
const Timer = ({ seconds }) => {
const [timeLeft, setTimeLeft] = useState('');
const now = Date.now();
const then = now + seconds * 1000;
const countDown = setInterval(() => {
const secondsLeft = Math.round((then - Date.now()) / 1000);
if(secondsLeft <= 0) {
clearInterval(countDown);
console.log('done!');
return;
}
displayTimeLeft(secondsLeft);
}, 1000);
const displayTimeLeft = seconds => {
let minutesLeft = Math.floor(seconds/60) ;
let secondsLeft = seconds % 60;
minutesLeft = minutesLeft.toString().length === 1 ? "0" + minutesLeft : minutesLeft;
secondsLeft = secondsLeft.toString().length === 1 ? "0" + secondsLeft : secondsLeft;
return `${minutesLeft}:${secondsLeft}`;
}
useEffect(() => {
setInterval(() => {
setTimeLeft(displayTimeLeft(seconds));
}, 1000);
}, [seconds])
return (
<div><h1>{timeLeft}</h1></div>
)
}
export default Timer;```
常量计时器=({seconds})=>{
const[timeLeft,setTimeLeft]=useState(“”);
const now=Date.now();
const then=现在+秒*1000;
常量倒计时=设置间隔(()=>{
const secondsLeft=Math.round((then-Date.now())/1000);
如果(第二次){
let minutesLeft=数学楼层(秒/60);
设secondsLeft=seconds%60;
minutesLeft=minutesLeft.toString().length==1?“0”+minutesLeft:minutesLeft;
secondsLeft=secondsLeft.toString().length==1?“0”+secondsLeft:secondsLeft;
返回`${minutesLeft}:${secondsLeft}`;
}
useffect(()=>{
设置间隔(()=>{
setTimeLeft(显示TimeLeft(秒));
}, 1000);
},[秒])
返回(
{timeLeft}
)
}
导出默认定时器```
常量计时器=({seconds})=>{
//使用秒道具初始化timeLeft
const[timeLeft,setTimeLeft]=使用状态(秒);
useffect(()=>{
//到达0时提前退出
如果(!timeLeft)返回;
//save intervalId可在以下情况下清除间隔:
//组件重新渲染
const intervalId=setInterval(()=>{
setTimeLeft(timeLeft-1);
}, 1000);
//在重新渲染时清除“间隔”,以避免内存泄漏
return()=>clearInterval(intervalId);
//将timeLeft添加为依赖项以重新运行效果
//当我们更新它的时候
},[timeLeft]);
返回(
{timeLeft}
);
};
挂钩和间隔的经典问题。查看并注意在拆卸时取消间隔是否在此处使用setTimer更有意义?@AmirShitrit您的意思是setTimeout
?两者都是有效选项,但setTimeout
假设在setInterval
假设触发三次时触发该函数g每x个时间点启动一次函数。由于useffect
的性质,我们需要在每次timeLeft
更改时设置并清除计时器,我想它不会真正起到“真实”的作用setInterval
在这种情况下,我可以看到您的setTimeout
点。是的。我的意思是设置超时。谢谢!@AmirShitrit是的,我更喜欢setTimeout
const Timer = ({ seconds }) => {
// initialize timeLeft with the seconds prop
const [timeLeft, setTimeLeft] = useState(seconds);
useEffect(() => {
// exit early when we reach 0
if (!timeLeft) return;
// save intervalId to clear the interval when the
// component re-renders
const intervalId = setInterval(() => {
setTimeLeft(timeLeft - 1);
}, 1000);
// clear interval on re-render to avoid memory leaks
return () => clearInterval(intervalId);
// add timeLeft as a dependency to re-rerun the effect
// when we update it
}, [timeLeft]);
return (
<div>
<h1>{timeLeft}</h1>
</div>
);
};