Можете ли вы очистить setInterval, если условие выполнено? без использования componentDidMount? - PullRequest
0 голосов
/ 02 апреля 2020

Я создаю простой таймер. Я хочу, чтобы таймер сбрасывался каждый раз, когда он достигает 00 секунд. Я использую setInterval, но его значение не очищается каждый раз 0 в this.state.seconds. Я видел некоторые решения, использующие componentDidMount и componentDidUnmount, но был бы заинтересован в том, чтобы выполнить и очистить setInterval из метода, который вызывает сам setInterval. Это что-то можно сделать?

До сих пор таймер продолжает уменьшаться даже через 0 секунд. Вот мой черновик кода: https://codepen.io/tonytony92/pen/bGdJeRg

class MyApp extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            minutes: 25,
            seconds: 59,
            play: false,
            display: "SESSION"
        }
        this.handlePlay = this.handlePlay.bind(this)
    }


    handlePlay() {
        let func1 = () => {
            this.setState({
                seconds: this.state.seconds - 1
            })
            console.log(this.state.seconds)
        }

        if (this.state.seconds > 0) {
            this.Myvar = setInterval(() => {
                console.log(this.state.seconds)
                this.setState({
                    seconds: this.state.seconds - 1
                })
            }, 200)
        }
        else {
            console.log("minus")
            clearInterval(this.Myvar)  /// not clearing ///
        }
    }
}

1 Ответ

1 голос
/ 02 апреля 2020

handlePlay запускает таймер при нажатии кнопки, но не проверяет остальное, как вы ожидаете.

Это потому, что функция, предоставленная setInterval, имеет значение

console.log(this.state.seconds)
this.setState({
  seconds: this.state.seconds - 1
})

, а не функция handlePlay.

Для лучшей читаемости и удобства обслуживания (а также для работы с кодом), разделите logi c, который обрабатывает уменьшение времени, от кода, запускающего таймер. Например:

class MyApp extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            minutes: 0,
            seconds: 10,
            play: false,
            display: "SESSION"
        }
        this.handlePlay = this.handlePlay.bind(this);
        this.handleTime = this.handleTime.bind(this);
    }

    // handlePlay only launches the timer.
    handlePlay() {
        this.Myvar = setInterval(this.handleTime, 200);
    }

    // handleTime deals with the logic of decrementing time.
    handleTime() {
        if (this.state.seconds > 0) {
            console.log(this.state.seconds)
            this.setState({
                seconds: this.state.seconds - 1
            })
        } else {
            console.log("minus")
            clearInterval(this.Myvar)
        }
    }
}

handlePlay теперь интерфейс между пользовательским интерфейсом (нажатие кнопки) и logi c (уменьшение времени обработки). Таймер запускается только с setInterval.

handleTime, который обрабатывает лог c уменьшения времени. Он вызывается каждый раз, когда setInterval срабатывает и останавливает таймер, когда время истекло.

...