this.setState is not a function

Тренируюсь с react.js. Написал простенький скрипт: счётчик. Принимает в пропсах стартовую позицию и шаг. По клику на кнопку показывает блок в котором каждую секунду обновляет {result} (из стартового значение вычитает шаг, пока не станет равным 0). При запуске счётчика на клик появляется ошибка this.setState is not a function

import React, { Component } from "react";

class Counter extends Component {

  constructor(props) {
    super(props);

    const { startPosition } = this.props;

    this.state = {
      result: startPosition,
      isCounting: false
    }
  }

  startCount(startPosition, step) {
    this.setState({ isCounting: true });

    let counter = setInterval(function () {
      if (startPosition > 0) {
        this.setState({ result: startPosition - step });
      } else {
        this.setState({ result: "That's all folks!" });
        clearInterval(counter);
      }

      startPosition = --startPosition;
    }, 1000)
  }

render() {
    const { startPosition, step } = this.props;
    const { result, isCounting } = this.state;

    return (
      <div>
        <button
          onClick={this.startCount.bind(this, startPosition, step)}
        >Start</button>

        <br/>
        <br/>

        <div>Start Position: {startPosition}</div>
        <div>Step: {step}</div>

        {isCounting && <div>
          <div> Now counting ({startPosition} minus {step})</div>
          <div>{result}</div>
        </div>}

      </div>
    )
  }
}

export default Counter;</code>

Ответы (1 шт):

Автор решения: RTK

Ошибка связана с потерей контекста this

в коде

let counter = setInterval(function () {
      if (startPosition > 0) {
        this.setState({ result: startPosition - step });
      } else {
        this.setState({ result: "That's all folks!" });
        clearInterval(counter);
      }

      startPosition = --startPosition;
    }, 1000)

this - указывает на текущую функцию, а не на класс в котором она вызвана

Нужно использовать стрелочную функцию, она не имеет своего контекста:

let counter = setInterval(() => {
      if (startPosition > 0) {
        this.setState({ result: startPosition - step });
      } else {
        this.setState({ result: "That's all folks!" });
        clearInterval(counter);
      }

      startPosition = --startPosition;
    }, 1000)

Узнать подробнее:

MDN bind (старый способ, в рамках саморазвития)

MDN Стрелочные функции

→ Ссылка