0

I am learning React, I find out there's two different ways to define methods in a Component Class.

one way is to define a method as a class method:

handleCategorySelected(category){
    this.setState({
        category
    })
};

but first need to bind method to this in constructor method.

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

After bind,I can use it in JSX.

render() {
    return <Fragment>
        <Footer
            onSelect={this.handleCategorySelected}
        />
    </Fragment>
}

Otherwise it will throw an Type error:

TypeError: Cannot read property 'setState' of undefined

The second way is more simple,

handleCategorySelected = (category) => {
    this.setState({
        category
    })
};

and after this definition,I can use this method in JSX without bind 'this' in the constructor method;

what's the different between two ways,and why is the first way throws an error without bind 'this',and why is the other way does not? what's the different?

Russell
  • 125
  • 2
  • 8
  • The arrow function ensures `this` inside the callback function is inherited from the surrounding scope, rather than it being something else from the handler with `onSelect={this.handleCategorySelected}` – CertainPerformance Dec 17 '18 at 05:03
  • you can read this article https://medium.com/quick-code/react-quick-tip-use-class-properties-and-arrow-functions-to-avoid-binding-this-to-methods-29628aca2e25 – Alex C Dec 17 '18 at 05:03

1 Answers1

2

Method 1 is called public class fields syntax, using it and we don't need to worry about the meaning of this in runtime because it's automatically bound. For example:

class LoggingButton extends React.Component {
  // This syntax ensures `this` is bound within handleCategorySelected.
  // Warning: this is *experimental* syntax.
  handleCategorySelected = () => {
    console.log('this is:', this);
  }

  render() {
    return (
      <button onClick={this.handleCategorySelected}>
        Click me
      </button>
    );
  }
}

In Method 2, it's just a normal method on the class, a common pattern is for an event handler when you define a component using an ES6 class

However, when using this method, you have to be careful about the meaning of this in JSX callbacks. In JavaScript, class methods are not bound by default. If you forget to bind this.handleClick and pass it to onClick, this will be undefined when the function is actually called.

class LoggingButton extends React.Component {
  constructor(props) {
    super(props);

    // This binding is necessary to make `this` work in the callback
    this.handleCategorySelected = this.handleCategorySelected.bind(this);
  }
  handleCategorySelected() {
    console.log('this is:', this);
  }

  render() {
    return <button onClick={this.handleCategorySelected}>Click me</button>;
  }
}

The difference between method 1 and method 2 is about the meaning of this inside the function when the function is actually called.


Reference: Handling Events