Fallc
Fallc

Reputation: 105

ComponentWillUnmount() doesn't clear interval

I have a countdown timer that should invoke a method once it turns to 0. Then, a new page is rendered and the countdown should reset and start again. It works as intended until the component unmounts. The method timeNext() gets then called every second because the interval doesn't stop anymore.

import React, { Component } from 'react';

class Countdown extends Component {

    state = {
        timer: this.props.timer
    }

    decrementTimeRemaining = () => {
        if (this.state.timer > 0) {
            this.setState({
                timer: this.state.timer - 1
            });
        } else {
            clearInterval(this.timerFunction);

            this.props.timeNext();
            this.setState({ timer: this.props.timer });
            this.decrement();
        }
    };

    decrement() {
        this.timerFunction = setInterval(() => {
            this.decrementTimeRemaining();
        }, 1000);
    }

    componentDidMount() {
        this.decrement()
    }

    componentWillUnmount() {
        console.log("unmounted")
        clearInterval(this.timerFunction);
    }

    render() {
        return (
            <div>{this.state.timer} </div>
        )
    }
}

export default Countdown;

I suspect it somewhere causes an infinite loop. I thought clearing the interval in componentWillUnmount() would work, but apparently there is a mistake. There seems to be an interval running even when the component gets unmounted and I don't know how to stop it.

Upvotes: 1

Views: 578

Answers (1)

Timothy Jannace
Timothy Jannace

Reputation: 1481

I think you've over-complicated your decrementTimeRemaining function. I would refactor the function like this:

decrementTimeRemaining = () => {
    if (this.state.timer > 0) {
        this.setState({
            timer: this.state.timer - 1
        });
    } else {
        this.setState({ timer: this.props.timer });
    }
};

Now componentWillUnmount is the only place that clearInterval is called and componentDidMount is the only place that the interval is started.

Upvotes: 1

Related Questions