Vue/React为什么组件销毁后定时器会继续

原因

在 Vue 和 React 中,组件销毁后定时器可能会继续运行,这是因为这两个框架都使用了虚拟 DOM 技术。虚拟 DOM 可以提高渲染效率和性能,但也带来了一些问题。

当我们在 Vue/React 组件中创建定时器时,实际上是在组件的生命周期方法(例如 mountedcomponentDidMount)中注册了该定时器。这意味着,在组件被销毁时,虽然页面上已经看不到该组件,但是组件实例却还存在于内存中,而其中包括已经注册的定时器。

因为 JavaScript 中的垃圾回收是一个自动的过程,并且回收时机是由垃圾回收机制自行控制的。当一个对象不再被引用时,它仍然可能在内存中保留一段时间,直到垃圾回收机制判断它不再可达时才会被回收。

具体回收时机取决于操作系统、浏览器和垃圾回收机制本身的实现。一般来说,这个过程是透明的,开发者无法精确控制。

如果我们没有在组件的生命周期方法中手动清除定时器,在组件被销毁后,该定时器仍然会继续运行,并且由于此时组件实例已经不存在于页面中,虚拟 DOM 无法监测到定时器的状态变化。这就导致该定时器将一直占用着内存和 CPU 资源,直到整个页面被关闭或刷新。

解决

为了避免这种情况的发生,我们需要在组件被销毁时手动清除其中创建的定时器。在 Vue 中,我们可以在 beforeDestroy 生命周期方法中清除定时器。

<template>
  <div>My Component</div>
</template>

<script>
import { onMounted, onUnmounted } from 'vue';

export default {
  setup() {
    let timerId = null;

    onMounted(() => {
      timerId = setInterval(() => {
        console.log('tick');
      }, 1000);
    });

    onUnmounted(() => {
      clearInterval(timerId);
    });
  },
};
</script>

在 React 中,我们可以在 componentWillUnmount 生命周期方法中清除定时器。

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.timerId = null;
  }

  componentDidMount() {
    this.timerId = setInterval(() => {
      console.log('tick');
    }, 1000);
  }

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

  render() {
    return <div>My Component</div>;
  }
}

猜你喜欢

转载自blog.csdn.net/weixin_42373175/article/details/130769971