If you’ve ever experienced performance issues whilst using React.js, it’s likely because your React components are needlessly re-rendering. Luckily, React provides an easy out of the box solution which is
shouldComponentUpdate. If you’ve never seen or used
shouldComponentUpdate, I made a post about it here.
shouldComponentUpdate shallow compares the props/state of the component and only when either has changed, does the component re-render; thus cutting out needless re-renders.
So... What's the problem?
Well the problem is, there’s been a pattern that I’ve been seeing quite a lot in the React.js community; using anonymous (arrow) functions as callback props. Here are two examples, the first with arrow functions, and the latter without. It’s immediately clear why people prefer the arrow function approach:
with ES6 Arrow Functions:
without ES6 Arrow Functions:
Looking at this code, I would probably pick the first one. With the introduction of arrow functions in ES6, it has never been easier to write anonymous functions, the first example using arrow functions looks very clean and legible (if I do say so myself :bowtie:).
HOWEVER, there is always more than meets the eye. The first example is actually REALLY BAD. The first component will cause the
CustomButtonComponent to re-render needlessly, even when we’ve optimized the component with
So why are arrow functions bad exactly?
Arrow functions used in this context are what’s known as
An anonymous function by nature has no reference, thus they will be redefined/recreated on every component render cycle. In our case, that means everytime
Main re-renders, it redefines the
onClicked prop of the
CustomButtonComponent to re-render even if has been optimized with
shouldComponentUpdate. This breaks the intended behaviour of
Here’s how we should rewrite this file so
CustomButtonComponent will only render as needed:
Here we’re passing the reference of
this._handleClicked, and therefore not creating a new function on every render. Now
CustomButtonComponent will receive the same callback prop everytime and won’t needlessly re-render. But don’t just take my word for it, I’ve created a working jsfiddle to demostrate the downside of using arrow functions as callback props, see for yourself here.
The downside to this approach is that you have to write some more code (most of which will boil a lot of plates); however the flip side is that you end up with optimized performance, and I think that’s a pretty big win.