反应倒数计时器不正确

时间:2020-07-23 20:03:33

标签: javascript reactjs

初学者在这里。我正在尝试将倒数计时器从3设置为0。该应用将秒数呈现到屏幕上,但它的确非常快。我尝试更改时间间隔,但似乎并没有使时间更加准确。我不知道怎么了。任何帮助表示赞赏。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".activityHome"
    android:background="@color/colorPrimary">



    <Button
        android:id="@+id/btnLogOut"
        android:layout_width="115dp"
        android:layout_height="75dp"
        android:text="log out"
        android:textSize="18sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <FrameLayout
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@id/bottom_navigation_bar" />

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_navigation_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?android:attr/windowBackground"
        app:itemTextColor="@color/colorPrimaryDark"
        app:itemIconTint="@color/colorPrimaryDark"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btnLogOut"
        app:layout_constraintVertical_bias="1.0"
        app:menu="@menu/bottom_navigation" />

</androidx.constraintlayout.widget.ConstraintLayout>

2 个答案:

答案 0 :(得分:0)

我会在这里使用componentDidMount开始间隔。您只希望创建一次间隔,然后在间隔倒数完成或计时器达到0之前卸下组件时对其进行清理。您可以在此之上构建额外的功能来执行诸如停止/重新启动的操作...等

export default class Timer extends React.Component {
  state = {
    time: this.props.start || 3
  };
  options = {
    interval: this.props.interval || 1000
    step: this.props.step || 1
  };
  interval = null;

  componentDidMount() {
    this.countdown()
  }
  componentWillUnmount() {
    clearInterval(this.interval)
  }
  tick = () => {
    this.setState(
      ({ time }) => ({ time: time - this.options.step }),
      () => {
        if (this.state.time === 0) {
          clearInterval(this.interval);
        }
      }
    );
  }
  countdown = () => {
    this.interval = setInterval(this.tick, this.options.interval);
  }

  render() {
    return (
      <div id="Timer">
        <p>{this.state.time}</p>
      </div>
    );
  }
}

Here's a demo to play with :)

答案 1 :(得分:0)

第一个对您的信息发表评论的用户是对的。但是让我澄清一下。

这就是我正在发生的事情。组件首次呈现时,执行timer()方法,该方法设置计时器间隔。在第一秒之后,将执行间隔回调,该回调将更改组件状态,并作出响应以计划重新渲染组件。然后,该组件重新渲染自身,并在设置新间隔的第二秒(请原谅此冗余短语)之前再次执行timer()函数。直到清除间隔(这是您的代码设置的最后一个间隔)之后,这种情况才会发生。这就是为什么您注意到可变时间更改的值异常快的原因。

您应该执行以下操作:(这是您的完全相同的代码,但有一些更改,可能对您理解起来更有用。然后您可以给出自己的样式或个人风格)

import React from "react";

export default class Timer extends React.Component {

constructor(){
    super();

    this.state = {
        time: 3,
    }

    this.countdown = this.countdown.bind(this);
    this.timer = this.timer.bind(this)
}

componentDidMount() {
  this.interval = setInterval(() => 
    this.countdown(interval),1000
  );
}

componentWillUnmount() {
  if (this.interval) {
     clearInterval(this.interval);
  }
}

countdown(){
    if(this.state.time == null)
    {
        console.log("NULL")
    }
    let myTime = this.state.time
    
    if(myTime > 0) {
        myTime--;
        this.setState({time: myTime})
        console.log(myTime)
    } else {
        clearInterval(this.interval)
    }

    return myTime;
}

render() {
  return (
    <div id = "Timer">
      <p>
          {this.state.time}
      </p>
    </div>
  );
}
}

干杯!