React定时器的设置与控制——多个定时器,手动开始和手动清除

一、js 定时器有以下两个方法:

  • setInterval() :按照指定的周期(以毫秒计)来调用函数或计算表达式。方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。
  • setTimeout() :在指定的毫秒数后调用函数或计算表达式。

   实现方式大同小异,这里以setInterval举例。

二、React 官方定时器的例子

class Timer extends React.Component {
  constructor(props) {
    super(props);
    this.state = {secondsElapsed: 0};
  }

  tick() {
    this.setState((prevState) => ({
      secondsElapsed: prevState.secondsElapsed + 1
    }));
  }

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

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

  render() {
    return (
      <div>Seconds Elapsed: {this.state.secondsElapsed}</div>
    );
  }
}

ReactDOM.render(<Timer />, mountNode);

也就是在componentDidMount()函数里设置定时,在componentWillUnmount()函数里清除定时器。这样定时器就会在页面加载的时候卸载掉定时器。tick()函数就是定期执行的函数,这里可以按照自己的需求进行设置。

这时候的定时器只会在组件生成时启动,组件卸载时停止。这样的好处是不用控制定时器,坏处是无法手动控制定时器的起停。

三、多个定时器的手动控制

import React, { Component } from 'react';

let timer1 = undefined;
let timer2 = undefined;
let timer3 = undefined;

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {secondsElapsed: 0};
  }

  componentDidMount() {
    this.timerStart1();
    this.timerStart2();    
  }

  componentWillUnmount() {
    clearInterval(timer1);
    clearInterval(timer2);
  }

  record1 = () => {
    this.setState((prevState) => ({
      secondsElapsed: prevState.secondsElapsed + 1
    }));
    console.log("timer1");
  }

  record2 = () => {
    console.log("timer2");
  }

  record3 = () => {
    console.log("timer3");
  }

  timerStart1 = () =>  {
    timer1 = setInterval(() => this.record1(), 1000);
  }

  timerStart2= () => {
    timer2 = setInterval(() => this.record2(), 1000);
  }

  timerStart3= () => {
    timer3 = setInterval(() => this.record3(), 1000);
  }

  timerStop1= () => {
    clearInterval(timer1);
  }

  timerStop2= () => {
    clearInterval(timer2);
  }

  timerStop3= () => {
    clearInterval(timer3);
  }

  render() {
    return (
      <div>
        <div>
          Seconds Elapsed: {this.state.secondsElapsed}
        </div>
        <div>
          <button onClick={this.timerStart1}>timerStart1</button>
          <button onClick={this.timerStop1}>timerStop1</button>
        </div>
        <div>
          <button onClick={this.timerStart2}>timerStart2</button>
          <button onClick={this.timerStop2}>timerStop2</button>
        </div>
        <div>
          <button onClick={this.timerStart3}>timerStart3</button>
          <button onClick={this.timerStop3}>timerStop3</button>
        </div>
        
      </div>
    );
  }
}

export default App;

在这段代码里,设置了三个定时器,并且设置了6个按钮,分别取控制这三个定时器的起停。timer1和timer2,是随组件加载后就启动的,timer3是手动点击启动后才会启动。运行代码,F12看console,自己体验。

未打开定时器timer3时:

打开定时器timer3时:

由上可知:

1.定时器可以随时的打开和清除,因此可以在自己需要的周期函数中进行调用;

2.定时器是可以用变量指代,可以通过变量名清除指定的定时器;

3.上面的代码未作判断,因此会出现定时器清除不掉的情况。具体操作是:同一个定时器点击启动两次以上,当再点击清除定时器时,只能清除一个定时器。原因是:只用了一个变量,变量被覆盖,只会清除最后一个定时器。

4.针对3所述,如果对定时器无差别对待,可以采用数组的形式把变量都存储起来,伪码如下:

let timer = null;
let timerList = []
timerStart = () => {
  timer = setInterval(()=> this.record(), 1000);
  timerList.push(timer)
} 

timerEnd = () => {
  timerList.forEach((item,index)=>{ clearInterval(item) })
  timerList = []
  timer = 0; 
}

5.针对3所述,如果每个定时器都有自己指定的任务,建议在启动定时器之前先进行检查,再启动定时,伪码如下:

timerStart = () =>{
  if (timer) {
    clearInterval(timer);
  }
  timer = setInterval(()=> this.record(), 1000);
} 

timerStop = () => {
  clearInterval(timer);
  timer = 0;
}

参考连接:

https://juejin.im/post/5aaa248d6fb9a028b410caa0

https://www.jianshu.com/p/da1f7e6dbb62

https://blog.csdn.net/qq_30053399/article/details/52204754

React 中的定时器通常涉及到如何在组件更新周期之外运行代码,比如执行某个操作一定时间后再停止,这在前端应用中非常常见。为了更好地理解和管理定时器的状态,React 提供了几种处理定时器的方式: ### 1. 使用 `setTimeout` 和 `clearTimeout` `setTimeout` 函数用于设置一个延迟后调用的函数。它接受三个参数: - 第一个参数是一个回调函数,即你要在指定毫秒数后执行的操作。 - 第二个参数是要等待的时间间隔(以毫秒为单位)。 - 第三个参数是一个唯一标识符,可以传递给 `clearTimeout` 或者 `clearInterval` 来取消这个定时器。 例如,在 React 组件中创建一个定时器可能会像这样: ```jsx import React from 'react'; class TimerExample extends React.Component { state = { currentTime: null }; componentDidMount() { this.timerID = setInterval( () => this.tick(), 1000 // 每隔一秒钟更新一次状态 ); } componentWillUnmount() { clearInterval(this.timerID); // 清除定时器以防内存泄漏 } tick() { const now = new Date().toLocaleTimeString(); console.log(now); this.setState({ currentTime: now }); } render() { return ( <div> Current Time: {this.state.currentTime} </div> ); } } export default TimerExample; ``` ### 2. `useEffect` Hook 在现代 React 开发中,推荐使用 `useEffect` 钩子来替代生命周期方法。`useEffect` 可以让你在组件挂载、卸载以及副作用(如设置定时器)发生时进行响应。下面是如何使用 `useEffect` 设置定时器的例子: ```jsx import React, { useEffect } from 'react'; function TimerComponent() { useEffect(() => { let timerID; if (props.active) { timerID = setInterval(() => { console.log('Timer is ticking...'); }, 1000); } return () => { clearInterval(timerID); }; }, [props.active]); // 依赖数组包含需要监视变化的变量 return <div>Timer Component</div>; } export default TimerComponent; ``` 在这个例子中,我们通过 `useEffect` 来检查 `props.active` 是否已更改。如果更改了,则设置定时器;当组件卸载或 `active` 属性变为 `false` 时清除定时器。 ### 相关问题: 1. **何时应该使用`setTimeout`而不是`setInterval`**?它们之间的区别是什么? - `setTimeout` 只会触发一次预定的任务,适用于只需要执行一次特定任务的情况。 - `setInterval` 则会在每次指定时间间隔后重复执行函数,适合需要定期执行的任务。 2. **如何优雅地取消一个已经设置的`setTimeout`或`setInterval`?** - 对于 `setTimeout`,可以使用 `clearTimeout`; - 对于 `setInterval`,可以使用 `clearInterval`。这两个函数都需要传入之前设置定时器时得到的唯一标识符作为参数。 3. **在 React 管理计时器时如何避免内存泄漏?** - 将定时器的 ID 存储在一个返回的清理函数中,并在组件卸载时调用该清理函数来取消定时器。这是使用生命周期方法或者 `useEffect` 的关键实践之一,防止不必要的资源占用和内存泄露。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值