Correct use of arrow functions in React Correct use of arrow functions in React javascript javascript

Correct use of arrow functions in React


I understand that arrow functions make things more efficient by not recreating the functions each render similar to how binding in the constructor works.

This is not true. It depends on where exactly are you using the Arrow function. If Arrow function are used in render method, then they create a new instance everytime render is called just like how bind would work. Consider this example

<div onClick={()=>{this.onClick()}}>Previous</div>

Here each time render is called an anonymous function is created and that function when called, calls this.onClick.

However consider the case below

onClick = () => {    console.log("Div is clicked")}

In above case, the arrow function does not recreate function everytime, but binds the context to the React component as An arrow function does not have its own this; the this value of the enclosing execution context is used. once when the class is instantiated. This is similar to how binding works is constructor. This is a part of proposed class fields for arrow functions and it isn't a ES6 feature,

To understand what you wish to ask, you must know that a function gets its context from where it is called. Check this question for more understanding.

In your case, you have used Arrow function to define prevItem and hence it gets the context of the enclosing React component.

prevItem = () => {    console.log("Div is clicked")}render(){    return (         <SecondClass prevItem={this.prevItem} />    )}

Now in its child, even if you call prevItem with any custom context, using bind or arrow function, prevItem when executed in parent i.e Main.js will get the context of its enclosing React component. And since you just wish to execute prevItem function and do not want to pass any data to this from the child, writing

<ThirdClass type="prev" onClick={()=>this.props.prevItem()} />

and

<div onClick={()=>{this.props.onClick()}}>Previous</div>

is simply useless and will only add to performance implication since new functions are created in SecondClass and ThirdClass everytime. You simply don't need to have these functions defined as arrow function and could just write

<ThirdClass type="prev" onClick={this.props.prevItem} />

and

<div onClick={this.props.onClick}>Previous</div>

since its already binded in the parent.

Now even if you have to pass some additional data to these function from ThirdClass and SecondClass, you shouldn't directly use Arrow function or bind in render. Have a look at this answer on How to Avoid binding in Render method


I understand that arrow functions make things more efficient by not recreating the functions each time they are referred to

This is not true.

Arrow functions handles the this context in a lexical way, where "normal" function do it dynamically. I wrote about the this key word in depth if you need more info about it.

On both of your examples of the inline arrow function, you are creating a new function instance on each render.
This will create and pass a new instance on each render

onClick={() => {}}

On the 3rd example you only have one instance.
This only pass a reference to an already existing instance

onClick={this.myHandler}


As for the benefits of arrow functions as class fields (there is a small down side, i will post it in the bottom of the answer), if you have a normal function handler that needs to access the current instance of the class via this:

myHandler(){  //  this.setState(...)}

You will need to explicit bind it to the class.
The most common approach will be to do it in the constructor because it runs only once:

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

If you use an arrow function as the handler though, you don't need to bind it to the class because as mentioned above, the arrow function use a lexical context for this:

myHandler = () => {  //  this.setState(...)}

With both approaches you will use the handler like this:

<div onClick={this.myHandler}></div> 

The main reason for taking this approach:

<div onClick={() => this.myHandler(someParameter)}></div>

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.
(There is a better approach for this, keep reading).

Running example for such use case: