The core of every component written in React is the render method. From my experience most performance issues are directly related to problematic render methods. To start off this React Native Performance series lets take a look at some of the less obvious things that can be causing performance issues in our render methods.

Arrow Functions

We all love them, but should be cautious when using them with React. Arrow functions are great, they let us quickly create new javascript function short hand. The consequence of this is exactly that, it creates a new function every time it is executed. For the most part in Javascript this isn’t a real issue. When it comes to the React render method this can quickly become an issue.

render(){

return (

<View>

<TouchableOpacity onPress={() => console.log('Hello!')}>

Click Me

</TouchableOpacity>

</View>

)

}

So what could be the harm here, the button is simply just logging out a string on press. But in fact, when React executes this render method it will always see a new function. The arrow function returns a new function every time. This causes React to think something has changed in our view, when in fact nothing has.

logHello(){

console.log('Hello!');

} render(){

return (

<View>

<TouchableOpacity onPress={this.logHello}>

Click Me

</TouchableOpacity>

</View>

)

}

Simply moving that function from inline to a method on our class we completely fix the issue. Now when React looks at this view it is always going to see a reference to the this.logHello function and not a new function.

Binding

Just like arrow functions, function binding and the render method are not friends.

logHello(){

console.log(‘Hello!’);

} render(){

return (

<View>

<TouchableOpacity onPress={this.logHello.bind(this)}>

Click Me

</TouchableOpacity>

</View>

)

}

This render method looks innocent but really it is quite the opposite. Just like before when we used an arrow function, this is going to always re-render.

It’s actually the same issue, the binding of this on the this.logHello function is returning a new function. So like before, when React is looking at this view, it is seeing a new function every time. Which in return causes React to re-render. Not exactly what we want to happen.

Bind isn’t all that bad, just in the render method. So lets take the example from above and fix it. We will still use bind but in a more efficient way.

constructor(props){

super(props);

this.logHello = this.logHello.bind(this);

} logHello(){

console.log(‘Hello!’);

} render(){

return (

<View>

<TouchableOpacity onPress={this.logHello}>

Click Me

</TouchableOpacity>

</View>

)

}

We are now binding this to method in our constructor. This works because it will only happen once when the class is constructed. Now whenever React looks at this view it is no longer seeing a new function, instead it sees a direct reference to our method which already has this bound to it.

Conclusion

This is generally good practice to follow from the start of a project. It can save you headaches and refactoring down the road. You wont start to see performance issues because of arrow functions or function binding until down the road. A good general rule is to keep your render methods clean and executing quick.

I actively develop a cross platform React Native app at WeDo.