loading...

re: State Vs Prop / Arrow Functions in React VIEW POST

FULL DISCUSSION
 

Avoid using arrow functions inside React components.

They are helpful! We don't have to bind our methods in the constructor in order to use the this keyword. But at what cost? Let's have a look.

class Thingie extends React.Component {
  doSomething = () => {
    console.log('I did that something');
  }

  doSomethingElse = () => {
    return true;
  }

  render() {
    return <Button onClick={this.doSomething}>Click me!</Button>
  }
}

Our code is pretty straightforward to read but it will transpile to something like the below code.

class Thingie extends React.Component {
  constructor(...args) {
    var _temp;

    return _temp = super(...args), this.doSomething = () => {
      console.log('I did that something');
    }, this.doSomethingElse = () => {
      return true;
    }, _temp;
  }

  render() {
    return React.createElement(
      Button,
      { onClick: this.doSomething },
      'Click me!'
    );
  }
}

As we can see above, a constructor has been created to hold our doSomething and doSomethingElse functions in order for them to hold the this keyword. Notice how both of them are added in the constructor, even though doSomethingElse doesn't even need the this keyword.

In the case we already had a constructor created, the above class would look like this

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

    this.doSomething = () => {
      console.log('I did that something');
    };
  }


  render() {
    return React.createElement(
      Button,
      { onClick: this.doSomething },
      'Click me!'
    );
  }
}

Cool, this is more readable, but still, our methods got moved inside the constructor.

There are many problems that can be caused by this methodology but one of the most important (for me) is performance.

When you create a function and call it 100 times, you will simply have 100 references of the same function. The same applies with our React components.

By that I mean that if we create a component, not using arrow functions for its methods, every time we construct that component and click that button, our click handler goes to find that original doSomething method.

Now when we create a component using arrow functions as the methods, we redefine those methods for all those 100 times we created it. So, instead of just one function with 100 references to it, we end up with 100 different functions that do the same thing!

So, having the above in mind, I think it's better to define our class components like the below code.

class Thingie extends React.Component {
  doSomething() {
    console.log('I did that something');
  }

  render() {
    return <Button onClick={this.doSomething}>Click me!</Button>
  }
}

When the above code gets transpiled, the only part that will change is the JSX.

Now, if we want to use the this keyword in our doSomething method, we can just go ahead and define a constructor, binding doSomething to this.

Straightforward, readable and doesn't have the aforementioned performance issues.

 

Some time ago I read a comment by a Polymer dev, that const arrows are faster.

mobile.twitter.com/justinfagnani/s...

 

I will have to disagree that arrow functions are faster than "normal" functions.
Arrow functions are just wrappers (syntactical sugar) of "normal" functions.

Even if they weren't, what we should not forget is that for production apps, es6 gets transpiled to es5 (most of the time).

// in the end this:
const thing = () => console.log('aha!');

//becomes this:
var thing = function thing() {
  return console.log('aha!');
};

However I like arrow functions, I dislike the fact that when transpiled, we end up with a variable x that references a function named x.
Now if we want to pass x to y, we will end up with y referencing x (the variable) that references x (the function). What a mess, right?

Why not just have a function x in the first place?

code of conduct - report abuse