(Hint: It makes shouldComponentUpdate and PureComponent cranky)
In a previous post, I explained how to extract React child components to avoid using bind or arrow functions in render. But I didn’t provide a clear demo to show why this is useful.
Here’s a quick example.
In this example, I’m using an arrow function in render to bind the relevant user ID to each delete button.
On line 35, I’m using an arrow function to pass a value to the deleteUser function. That’s a problem.
To see why, check out User.js (click the hamburger icon on the top left to select different files in the example). I’m logging to the console each time render is called. I’ve declared User as a PureComponent. So User should only re-render when props or state change. But when you click on delete for a user, note that render is called for all User instances.
Here’s why: The parent component is passing down an arrow function on props. Arrow functions are reallocated on every render (same story with using bind). So although I’ve declared User.js as a PureComponent, the arrow function in User’s parent causes the User component to see a new function being sent in on props for all users. So every user re-renders when any delete button is clicked. 👎
Avoid arrow functions and binds in render. It breaks performance optimizations like shouldComponentUpdate and PureComponent.
What Should I Do Instead?
For contrast, here’s an example that doesn’t use an arrow function in render.
In this example, index.js has no arrow function in render. Instead, the relevant data is passed down to User.js. In User.js, onDeleteClick calls the onClick function passed in on props with the relevant user.id.
With this change, when you click on delete, notice that render isn’t called for the other Users! 👍
For optimal performance,
- Avoid arrow functions and bind in render.
- How? Extract child components, or pass data on the HTML element.
Looking for More on React? ⚛️