ES6 functions, arrow functions and 'this' in an ES6 class

class App extends Component {
  constructor(props) {
    ...
  }

  onChange = (e) => this.setState({term: e.target.value})

  onSubmit(e){
    e.preventDefault();
    const api_key = "C1hha1quJAQZf2JUlK";
    const url = `http://api.giphy.com/v1/gifs/search?q=${this.state.term}&api_key=${api_key}`;
  }

  render() {
    return (
      <div>
        <form onSubmit={this.onSubmit}>
          <input value={this.state.term} onChange={this.onChange}/>
          <button>Search!</button>
        </form>
      </div>
    );
  }
}

What is the difference between the two type of functions declared in the class (onChange and onSubmit). I get an error on referencing this.sate in const url if I declare it as an ES6 class method but changing it to arrow function fixes it.

I want to know how exactly 'this' is handled in both the cases

Also, how do I do it the other way? Say, if I want to use the same onSubmit function (ES6 class method) but want to handle this when I call it (in the form element), how do I do it ?

Using this.onSubmit.bind(this) ?

Answers 1

  • It's important to know that this syntax:

    class A {
      method = () => {}
    }
    

    is just syntactic sugar for creating an instance method in the class constructor:

    class A {
      constructor() {
        this.method = () => {}
      }
    }
    

    Note: This syntax is not an official part of the JavaScript language yet (currently in stage 3) so you must use a transpiler like Babel to handle it.

    The value of this within method is the class A because that is what this points to in the constructor (since arrow functions inherit the context from the scope they are defined in):

    class A {
      constructor() {
        this.method = () => this;
      }
    }
    
    const instance = new A();
    console.log(instance.method() === instance); // true

Related Articles