【问题标题】:Stop interval function when changing site更换站点时停止间隔功能
【发布时间】:2018-08-30 13:48:12
【问题描述】:

我正在使用 react 编写一个网站。在一个组件中,我有一个被执行的setInterval() 函数,它会更新它们DOM。现在,当我使用路由器 (react-router-dom) 切换到另一个站点时,setInterval() 函数崩溃了,因为它找不到要更新的 DOM 元素。我该怎么做呢?我虽然使用componentWillUnmount(),但发生了同样的错误。

class Counter extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            stop: false,
        }
    }

    componentWillUnmount() {
        if(!this.state.stop) {
            this.setState({
                stop: true,
            })
        }
    }

    _stop = (counter) => {
        clearInterval(counter);
    }

    _someFunc = () =>  {
        ...
    }

    render() {
        ...
        const update = setInterval(function () {
            document.getElementById('some-id').innerText = this._someFunc();
        }, 1000);

        if(this.state.stop) {
            this._stop(update)
        }

        return (
                <p id='some-id'></p>
        )
    }
}

export default Counter;

TypeError: document.getElementById(...) 为空。

如何停止间隔?

【问题讨论】:

  • 在将文本放入之前检查元素是否存在。
  • @SenadMeškin 会产生大量不必要的 if/else 问题。
  • 看来你应该在卸载部分调用 stop。

标签: javascript reactjs setinterval


【解决方案1】:

变化:

1- 将定时器放在render方法之外,最好使用componentDidMount生命周期方法。这样定时器只会注册一次,每1ms就会执行一次回调方法。

2- 将计时器 id 存储在一个变量中(在实例中)以在离开页面之前停止它。

像这样:

class Counter extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            stop: false,
        }
    }

    componentDidMount() {
        this.timerId = setInterval(function () {
            document.getElementById('some-id').innerText = this._someFunc();
        }, 1000);
    }

    componentWillUnmount() {
        this._stop();
    }

    _stop = () => {
        clearInterval(this.timerId);
    }

    _someFunc = () =>  {
        ...
    }

    render() {

        return (
                <p id='some-id'></p>
        )
    }
}

export default Counter;

【讨论】:

  • 啊,所以只有this.timerId = setInterval ...const update = setInterval.... 不同?为什么我需要将它存储在一个类(?)变量中,而不能像我那样存储间隔?
  • 如果你在局部变量中设置值,它不会在所有函数中都可用。如果您存储在类实例中,它将很容易获得。
  • 您的代码的另一个问题是,在每次重新渲染组件时,都会注册一个新的计时器而不是使用相同的计时器,以避免在使用 setInterval 之前进行检查:)
【解决方案2】:

如果不是性能优化那就做反应方式

https://stackoverflow.com/a/39426527/6124657

【讨论】:

    猜你喜欢
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-27
    • 1970-01-01
    • 2021-11-06
    相关资源
    最近更新 更多