在 React 中使用 Hooks 实现倒数计时器 [英] Implementing a countdown timer in React with Hooks

查看:309
本文介绍了在 React 中使用 Hooks 实现倒数计时器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 React 钩子在屏幕上呈现倒数计时器,但我不确定呈现它的最佳方式.

我知道我应该使用 useEffect 来比较当前状态和以前的状态,但我认为我做得不对.

非常感谢您的帮助!

我尝试了几种不同的方法,都没有奏效,比如每当更新时设置状态,但它最终会像疯了一样闪烁.

<代码>const 定时器 = ({ 秒 }) =>{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) {清除间隔(倒计时);console.log('完成!');返回;}displayTimeLeft(secondsLeft);}, 1000);const displayTimeLeft = 秒 =>{让minutesLeft = Math.floor(seconds/60) ;让 secondsLeft = 秒 % 60;minutesLeft = minutesLeft.toString().length === 1 ?0"+ 分钟左:分钟左;secondsLeft = secondsLeft.toString().length === 1 ?"0" + secondsLeft : secondsLeft;返回`${minutesLeft}:${secondsLeft}`;}useEffect(() => {setInterval(() => {setTimeLeft(displayTimeLeft(seconds));}, 1000);}, [秒])返回 (<div><h1>{timeLeft}</h1></div>)}导出默认计时器;```

解决方案

const Timer = ({ seconds }) =>{//用 seconds 属性初始化 timeLeftconst [timeLeft, setTimeLeft] = useState(seconds);useEffect(() => {//当我们到达 0 时提前退出如果(!timeLeft)返回;//保存 intervalId 以清除间隔时//组件重新渲染const intervalId = setInterval(() => {setTimeLeft(timeLeft - 1);}, 1000);//清除重新渲染的间隔以避免内存泄漏返回 () =>clearInterval(intervalId);//添加 timeLeft 作为依赖重新运行效果//当我们更新它时}, [剩下的时间]);返回 (<div><h1>{timeLeft}</h1>

);};

Im trying to render a count down timer on screen with react hooks, but I'm not sure the best way to render it.

I know i'm supposed to use the useEffect to compare current state to previous state, but I don't think I'm doing it correctly.

I would appreciate the help!

I've tried a couple of different ways, none of them work, like setting state whenever whenever it updates, but it just ends up flickering like crazy.



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;```

解决方案

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>
  );
};

这篇关于在 React 中使用 Hooks 实现倒数计时器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆