Alexander Mills
Alexander Mills

Reputation: 100000

ES6 and ES8 syntax in React Component

I am new to ES6 with React, and see this inexplicable code in a component:

   componentWillUnmount() {
        base.removeBinding(this.ref);
        this.unsubscribe();
    }

    // ES6 syntax
    handleToggle(event, toggled){
        this.setState({
            [event.target.name]: toggled,
        });
    };

    // possible ES8 syntax
    handleToggle = (event, toggled) => {
        this.setState({
            [event.target.name]: toggled,
        });
    };

the second method is confusing me, what exactly is happening with the handleToggle method? Is there an ES5 equivalent?

My guess that the ES5 equivalent is:

   componentWillUnmount: function() {
        base.removeBinding(this.ref);
        this.unsubscribe();
    }

    handleToggle: (event, toggled) => {
        this.setState({
            [event.target.name]: toggled,
        });
    };

...the problem/confusing part with the second method, is that 'this' in the handleToggle method will be bound to the wrong value (the lexical scope 'this' value)...so is this syntax even valid here?

what is going on? This is code in someone else's library that I wish to understand.

Upvotes: 0

Views: 1744

Answers (2)

Felix Kling
Felix Kling

Reputation: 816364

what exactly is happening with the handleToggle method?

This is a new feature that is a proposal called public class fields. Currently the ES6 class syntax only provides syntactic support for defining shared methods, but not for instance methods/properties. This proposals extend the class syntax to support that.

Here is a simple example:

class Foo {
  bar = 42;
}

is equivalent to

class Foo {
  constructor() {
    this.bar = 42;
  }
}

I.e. those properties are evaluated as if they are assign to this inside the constructor.

Consequently your example is equivalent to

class Component extends React.Component {
  constructor()
    this.handleToggle = (event, toggled) => {
        this.setState({
            [event.target.name]: toggled,
        });
    };
  }
}

Due to the nature of arrow functions, this creates "bound" instance methods and thus can be passed to other functions without loosing the value of this.

so is this syntax even valid here?

No officially released version of ECMAScript contains this feature, so strictly speaking the answer should be: no. However, it is on the standards track, so it will likely be part of ES2018.

In the meantime its possible to use this proposal in your own code by using Babel (which needs to be used for React anyway) with the transform-class-properties plugin.

Upvotes: 4

Shubham Khatri
Shubham Khatri

Reputation: 281656

The handleToggle function here makes use of the arrow functions

handleToggle = (event, toggled) => {
    this.setState({
        [event.target.name]: toggled,
    });
};

It takes two arguments event, toggled and whatever is after the => is the body of the function. One speciality of arrow functions is that is does the binding action too.

The ES5 equivalent of the above function would be

handleToggle: function(event, toggled){
    this.setState({
        [event.target.name]: toggled,
    });
};

while calling this function you will need to bind it explicitly like this.handleToggle.bind(this, value)

Upvotes: 0

Related Questions