Search code examples
javascriptreactjsecmascript-nextclass-fields

In a React Component, what's the difference between foo(){} and bar = () => {} and when should I use which?


Babel is doing its magic, which makes me very confused about what's going on.

What's the difference between foo and bar in this react Component? And when should I use which?

class MyComponent extends Component {
  foo() {
    //...
  }
  bar = () => {
   //... 
  }
}

(My own guess is foo is in the prototype, and bar is in the constructor? Anyways, I don't know what I'm talking about)


Solution

  • My own guess is foo is in the prototype, and bar is in the constructor?

    That's exactly right.

    foo() {}
    

    in this context is a method declaration and the value gets assigned to the prototype. It's equivalent to

    MyComponent.prototype.foo = function() {};
    

    bar = ... ;
    

    on the other hand is a class field. This is a shorthand notation for assigning properties to the instance in the constructor:

    constructor() {
      this.bar = ... ;
    }
    

    And because of how arrow functions work, using class fields with arrow functions basically lets you create "bound" methods.

    More on arrow functions: Arrow function vs function declaration / expressions: Are they equivalent / exchangeable?


    And when should I use which?

    The tl;dr is: Use class field + arrow function when you need a bound function.

    When do you need a bound function? Whenever you want this inside the function to refer to a specific value but you don't control how the function is called.

    That's mostly the case for event handlers (i.e. functions that are passed to other functions / components) that need to access the component instance (e.g. call this.setState or access this.props/this.state).

    You don't have to use it though, you could also bind the method when you need to. However, binding a method only once in the constructor is ideal for React components so that, if the method is passed as event handler, always the same function object is passed.


    As noted in another answer, this is not related to React at all. Class fields are likely officially integrated into the language this year.