Arrow vs function expression in React. When use the arrow and when use expression way

There are so many answers around this topic, because is about to use new ES6 feature in a recent framework such React that has the use of Arrow functions still as proposal way.

So I decided to investigate the topic further to clarify it to myself and to the readers bringing as much as possible updated example.

Let's start from the docs that recommend the use of function expression in this way:

class Foo extends Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }
  handleClick() {
    console.log('Click happened');
  }
  render() {
    return <button onClick={this.handleClick}>Click Me</button>;
  }
}

So with a class based Component aka a component that has to manage the state, then when we want do something with the data, this is still the way to go because it was like this from the beginning but also for choice to bind the this to the class constructor.

The same with arrow function is still on Stage 3 Proposal, but would be like:

class Foo extends Component {
  handleClick() {
    console.log('Click happened');
  }
  render() {
    return <button onClick={this.handleClick.bind(this)}>Click Me</button>;
  }
}

So when which one is the preferred one?

Well it depends, as usual.

First if depends if we have Functional Components that do not change the state, in this case the arrow function enable us to avoid to use bind as in arrow function the this has a context lexical scope, meaning its value is the one outside of the arrow function environment, as arrow functions do not have their own this, so we are sure of its value or we want that it is exactly the outside's function one!

This is the advantage, on the contrary there is a disadvantage, each arrow function does create a new object instance once is called, and so in React case each time the Component is rendered.

Let's see in code:


import React from 'react'
import ReactDOM from 'react-dom'

class Button extends Component {
  render() {
    return (
      <button
        onClick={() => this.setState({ backgroundColor: 'red' })}
        style={this.state}>
        Set background to red
      </button>
    )
  }
}

ReactDOM.render(
  <Button />,
  document.getElementById('root')
)

In this particular case actually the arrow function way is the only way to avoid a bag regarding this that its value is dynamically set.

As indeed in this case

import React from 'react'
import ReactDOM from 'react-dom'

class BrokenButton extends Component {
  render() {
    return (
      <button onClick={this.handleClick} style={this.state}>
        Set background to red
      </button>
    )
  }

  handleClick() {
    this.setState({ backgroundColor: 'red' })
  }
}

ReactDOM.render(
  <BrokenButton />,
  document.getElementById('root')
)

The color won't change at least we had bind the this as above, because the handleClick method isn’t a method at all! JavaScript doesn’t actually have methods. It only has functions. And the value of this inside those functions has some funny rules. In this case, those rules cause this to be null.

The thing to watch out with use arrow function in rendering part of a React component is that every time a new object is created and so new reference is created and this is true also with arrow function.

So The main reason for taking the above approach in which we use in the render an arrow function is if you want to pass parameters to the handler beside the native event that get passed, meaning you want to pass a parameter upwards.

As mentioned, this will create a new function instance on each render. But there is a better approach in this case.

A better approach would be to create component composition. You can create a child component that wraps the relevant markup, will have it's own handler and will get both the data and handler as props from the parent.

The child component will then invoke the handler that it got from the parent and will pass the data as a parameter.

Writing regarding this subject where much useful many relevant questions and answer on Stackoverflow such, and I plan to expand the topic with more example

stackoverflow.com/questions/52031147/react-..

stackoverflow.com/questions/48699573/correc..

stackoverflow.com/questions/45053622/how-to..

stackoverflow.com/questions/34361379/are-ar..

Also those other articles:

frontarm.com/james-k-nelson/when-to-use-arr..

medium.com/@oleg008/arrow-functions-in-reac..

freecodecamp.org/news/react-binding-pattern..

No Comments Yet