-2

I'm just starting to learn ES6 & ReactJS coming from a ES5 background.

I've been scratching my head with this ES6 code.

Code#1:

class App extends Component {

    constructor(props) {
       super(props);
       this.state = { videos: [] };

        YTSearch({key: API_KEY, term: 'surfboard'}, function(data) {
            this.setState({ videos: data }); **//I GET AN ERROR HERE!!**
        });
    }

    render() {
        return (
            <div>
                <SearchBar />
            </div>
        );
    }
}

I get an error in this.setState

bundle.js:19826 TypeError: Cannot read property 'setState' of undefined(…)

But, if I do

Code#2:

YTSearch({key: API_KEY, term: 'surfboard'}, (data) => {
    this.setState({ videos: data }); **//I GET AN ERROR HERE!!**
});

This works fine.

I can understand in first case, the scope of this in a general function is different in a callback (like AJAX). But how does that change in example #2?

Randy
  • 9,419
  • 5
  • 39
  • 56
TechnoCorner
  • 4,879
  • 10
  • 43
  • 81
  • 6
    [Did you, you know, look into the `() => { }` syntax at all?](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions) – Marty May 23 '16 at 06:40
  • Thank you my bad. Excuse me. I just started coding in reactJS / ES6. Just trying to get used to the new syntax. you guys rock! – TechnoCorner May 23 '16 at 06:43

2 Answers2

3

In ES6 when you write a fat arrow / lamda function the this context is retained (which is why your second example works).

But in your first example you use function() {} the this context is not retained, so the 'this' inside the function isn't what you're expecting it to be, it's a new context for the function.

dougajmcdonald
  • 19,231
  • 12
  • 56
  • 89
0

The if binding is set to the callsite with normal function statements, but with fat arrows, the callsite is not being set dynamically.

That being said; the this inside the function is what you expect it to be, after you read this. Very useful in JQuery functions because usually, you can do this:

regular function

function hi(){
    var name;
    $('element').on('action', function(){this.name = 'hi'});

    //now the name var is undefined;
    //instead, the object (element) has a property called name with 'hi'.
}

fat arrow

function hi(){
    var name;
    $('element').on('action', () => this.name = 'hi');

    //now the name var is 'hi';
    //the object (element) has no property 'name' now.
}
Randy
  • 9,419
  • 5
  • 39
  • 56