Should you use arrow functions in React components?

With the release of ES6 arrow function syntax, you now can use both regular JavaScript function and arrow function syntax when creating components. I would say that using the arrow function for React components is the right choice for most use cases.

Let’s consider the basics of both syntaxes first. Here’s how you write a normal function:

function sum(x, y){
  return x+y
}

And here’s the arrow function equivalent:

const sum = (x, y) => x + y

When you have only one argument, you can skip adding the round brackets:

const add = x => x + 1

Notice how the arrow function doesn’t need a return statement when there is only one line of code. You can even put the return on the next line:

const sum = (x, y) => 
x + y

But you still need a return statement when you have at least 2 lines of code:

const sum = (x, y) => {
  console.log("Running sum function")
  return x + y
}

The arrow function is far more concise than the regular function syntax, but when you use it inside React, it has the following benefits as well:

Arrow function prevents this keyword bug

The regular function syntax changes the context of this keyword. When you write a class component, you can’t call on this.setState without binding the function that calls it. The following example would throw an error when you click on the button:

class App extends React.Component {
  state = {
    name: "Johnson"
  }

  handleClick(){
    this.setState({name: "Jack"})
  }

  render(){
    return (
      <div>
        <p>My name is {this.state.name}</p>
        <button onClick={this.handleClick}>
          Change name
        </button>
      </div>
    )
  }
}

This is because the this inside handleClick() refers to the function context, while setState() function is a property of the App class. To solve the error, you need to bind the function this.handleClick when you pass it into the onClick prop:

<button onClick={this.handleClick.bind(this)}>

Or you can also bind it in the constructor:

class App extends React.Component {
  constructor(props){
    super(props)
    this.state = {
      name: "Johnson"
    }
    this.handleClick = this.handleClick.bind(this)
  }

  handleClick(){
    this.setState({name: "Jack"})
  }

  render(){
    return (
      <div>
        <p>My name is {this.state.name}</p>
        <button onClick={this.handleClick}>
          Change name
        </button>
      </div>
    )
  }
}

Now here’s one of the benefits using the arrow function: it doesn’t change the context of this keyword, so you don’t need to bind at all:

handleClick = () => {
  this.setState({name: "Jack"})
}

render(){
  return (
    <div>
      <p>My name is {this.state.name}</p>
      <button onClick={this.handleClick}>
        Change name
      </button>
    </div>
  )
}

This might seem trivial when you only have one function, but when you have more than three functions inside your component, you need to bind them all into the class component. Forgetting to bind a function is one of the most common causes of bugs in React.

By using the arrow function, you effectively removed the bind and this bugs.

Using the arrow function in render

Another way to remove the need for bind is to pass an arrow function into the onClick prop:

handleClick(){
  this.setState({name: "Jack"})
}

render(){
  return (
    <div>
      <p>My name is {this.state.name}</p>
      <button onClick={ () => this.handleClick() }>
        Change name
      </button>
    </div>
  )
}

Passing an arrow function in render will cause React to create a new function each time the component renders. But you don’t need to worry because the impact on performance is very minuscule. It’s very unlikely that your users will experience a noticeable lag just because of arrow functions in render.

But if you want to avoid removing the arrow function for performance reasons in the future, just create the function in arrow syntax and pass it to the onClick normally.

Take your skills to the next level ⚡️

I'm sending out an occasional email with the latest tutorials on programming, web development, and statistics. Drop your email in the box below and I'll send new stuff straight into your inbox!

No spam. Unsubscribe anytime.