1

Why is someFunction not being fired in the following snippet? I get an error: someFunction is not a function.

class MyComponent extends React.Component {

  constructor(props) {
    super(props);
    this.setInterval = this.setInterval.bind(this);
    this.someFunction = this.someFunction.bind(this);
  }

  setInterval = () => {
    console.log('Set Interval');
    setTimeout(function () {
        this.someFunction()
    }, 2000);
  }

  someFunction = () => {
    console.log('Some function');
  }

  componentDidMount() {
    this.timer = this.setInterval();
  }
}
norbitrial
  • 14,716
  • 7
  • 32
  • 59
Pim
  • 445
  • 1
  • 8
  • 24

4 Answers4

3

Because the way you are referring "this" is incorrect. You might wanna go with these options:

Option 1: Explicit binding using bind()

setInterval = () => {
    setTimeout(this.someFunction.bind(this), 2000);
}

Option 2 : Use a fat arrow function

setInterval = () => {
    setTimeout(() => {
        this.someFunction()
    }, 2000);
  }
joy08
  • 9,004
  • 8
  • 38
  • 73
2

That's technically a scoping issue. someFunction does not exist on that this what you have in the function passed to setTimeout.

Workaround which could work:

setInterval = () => {
    const self = this;

    setTimeout(function () {
        self.someFunction()
    }, 2000);
}

Or using () => { } like the following:

setInterval = () => {
    setTimeout(() => this.someFunction(), 2000);
}

I hope this helps!

norbitrial
  • 14,716
  • 7
  • 32
  • 59
1

Try using an arrow function inside setInterval.

setInterval = () => {
    console.log('Set Interval');
    setTimeout(function () {
        this.someFunction()
    }, 2000);
  }

can be

setInterval = () => {
    console.log('Set Interval');
    setTimeout(() => {
        this.someFunction()
    }, 2000);
  }

The first snippet fails because the this doesn't refer to the correct this. There are a lot of questions and answers regarding this on StackOverflow, you can search for them for a more detailed explanation.

Ramesh Reddy
  • 10,159
  • 3
  • 17
  • 32
0

The someFunction is out of scope. You don't need to bind 'this' if you are using arrow functions.

This is the simplest version of your component. Try this

class MyComponent extends React.Component {

  setInterval = () => {
    console.log('Set Interval');
    setTimeout(this.someFunction, 2000);
  }

  someFunction = () => {
    console.log('Some function');
  }

  componentDidMount() {
    this.timer = this.setInterval();
  }

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

Don't forget to clear the timer object inside componentWillUnmount.