如何使用 ReactJS 渲染倒计时功能

IT技术 javascript reactjs
2022-07-18 00:31:55

我一直试图让 countDown() 函数在 render() 函数中自动运行,但似乎无法弄清楚。这是代码:

import React from 'react';
import ReactDOM from 'react-dom';

class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.countDown = this.countDown.bind(this);
    this.state = {
      count: 5,
      message: ''
    }
  }
  countDown() {
    setInterval(() => {
      if (this.state.count <= 0) {
        clearInterval(this);
        this.setState(() => {
          return {message: "Click here to skip this ad"}
        }) 
      } else {
        this.setState((prevState) => {
          return {count: prevState.count - 1}
        }) 
      }
    }, 1000)
  }  
  render() {
    return (
      <div>
        <h1 onLoad={this.countDown}>
          {this.state.message ? this.state.message : this.state.count}
        </h1>
      </div>
    )
  }
}

ReactDOM.render(<Counter />, document.getElementById('app'));

我什至不确定这是否是最佳方法。我的目标是在屏幕上显示 5 秒倒计时,然后在倒计时为零时将其替换为下载消息/链接。

3个回答

用于componentDidMount启动间隔并清除它(可以肯定)componentWillUnmount

然后this.setState正确使用

class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 5,
      message: ''
    }
  }
  
  componentDidMount() {
    this.inter = setInterval(() => {
      if (this.state.count <= 0) {
        clearInterval(this.inter);
        this.setState({
          message: 'Click here to skip this ad'
        }); 
      } else {
        this.setState((prevState) => ({count: prevState.count - 1})); 
      }
    }, 1000);
  }
  
  componentWillUnmount() {
    clearInterval(this.inter);
  }
  
  render() {
    return (
      <div>
        <h1>
          {this.state.message ? this.state.message : this.state.count}
        </h1>
      </div>
    )
  }
}

ReactDOM.render(<Counter />, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>

我建议打电话countDowncomponentDidMount也建议将其存储interval并清除它componentWillUnmount

正如您所知道的,您的倒计时方法将无限期运行,这主要是 SetIntervals 的情况。还要尽量避免使用 onLoads 来调用事件处理程序。你应该做的是利用 React 提供的组件生命周期方法。具体来说ComponentDidMount()ComponentDidUpdate()在你的情况下。

对于您的倒计时,请尝试使用类似这样的东西

class Clock extends React.Component {
    state = {
       counter: 10
    }

//immediately is triggered. This only happens once. And we have it immediately call our countdown
componentDidMount() {
    this.countDown()
}

countDown = () => {
    this.setState((prevState) => {
        return{
            counter: prevState.counter - 1
        }
    })
}

//will get called everyt time we update the component state
componentDidUpdate(){
    if(this.state.counter > 0){
        setTimeout(this.countDown, 1000) //calls the function that updates our component state, thus creating a loop effect
    }
}

render() {
    return (
        <div className="time">
            The time is: {this.state.counter}
        </div>
    );
}

}