1

I dont understand a syntax difference between vanilla javascript and ES6 in a React Application. My first code that doesn't work is

class App extends Component{
constructor(props){
super(props);

this.state = {videos:[]};

YTSearch({key: API_KEY,term :'surfboards'},function(videos){
  this.setState({videos : videos});
});
}

This gives a 'Cannot read property 'setState' of undefined' error in the console

but changing the syntax to

YTSearch({key: API_KEY,term :'surfboards'},(videos)=>{
   this.setState({videos : videos});
});

fixes the problem. Isn't both the same thing(I may be wrong).Using

function(videos){}

and

(videos) => {}

I am not comfortable with javascript so any help is appreciated.

Paul Fitzgerald
  • 11,770
  • 4
  • 42
  • 54
  • 3
    Possible duplicate of [Arrow function vs function declaration / expressions: Are they equivalent / exchangeable?](https://stackoverflow.com/questions/34361379/arrow-function-vs-function-declaration-expressions-are-they-equivalent-exch) – 4castle Aug 16 '17 at 20:37

2 Answers2

5

This is due to how this is bound.

When using an arrow function this is still bound to your App class.

However, when you use the function keyword this is bound to that function.

As per MDN

Until arrow functions, every new function defined its own this value.

Using the function keyword you could take two approaches.

Firstly,

YTSearch({key: API_KEY,term :'surfboards'}, function(videos){
  this.setState({
      videos : videos
   });
}.bind(this));

or else you could do:

//assign this to new variable that to use when setting state
let that = this;

YTSearch({key: API_KEY,term :'surfboards'}, function(videos){
  that.setState({
      videos : videos
   });
});
Paul Fitzgerald
  • 11,770
  • 4
  • 42
  • 54
2

this refers to function. I suggest using ES6 arrow function:

class App extends Component{
  constructor(props){
    super(props);

    this.state = {videos:[]};

    YTSearch({key: API_KEY,term :'surfboards'}, (videos) => {
      this.setState({videos : videos});
    });
  }
}

It's because arrow function does not create its own this, the this value of the enclosing execution context is used. You can also store reference to this in variable (or bind function):

class App extends Component{
  constructor(props){
    super(props);

    var _this = this;

    this.state = {videos:[]};

    YTSearch({key: API_KEY,term :'surfboards'}, function(videos){
      _this.setState({videos : videos});
    });
  }
}
Artur
  • 628
  • 6
  • 14