Cache your React event listeners to improve performance.

An in-depth tutorial on how to cache functions

An under-appreciated concept in JavaScript is how objects and functions are references, which directly impacts React performance. If you were to create two completely identical functions, they are still not equal. Try for yourself:

But check out the difference if you assign a variable to an already-existing function:

Objects work the same way:

If you have experience in other languages, you may be familiar with pointers. What is happening here is that each time you create an object, you are allocating some amount of memory on the device to it. When I said that object1 = {} , I have created a chunk of bytes in the user’s RAM that is dedicated specifically to object1 . It is fair to imagine object1 as an address that contains where in RAM its key-value pairs are located. When I said object2 = {} , I created a different chunk of bytes in the user’s RAM that is dedicated specifically to object2 . Does the address of object1 match the address of object2 ? No. That is why the equality check for the two variables does not pass. Their key-value pairs may be exactly the same, but their addresses in memory are different and that is what is being compared.

When I assigned object3 = object1 , I am assigning the value of object3 to be the address of object1 . It is not a new object. It is that same location in memory. You can verify this like so:

In this example, I created an object in memory and assigned it to object1 . I then assigned object3 to that same address in memory. By mutating object3 , I have changed the value at that location in memory, meaning all other references to that location in memory change as well. object1 , which still points to that location in memory, now has a changed value.

This is a very common error for junior developers to make and likely warrants an in-depth tutorial of its own, but this particular tutorial is about React performance, which may be compromised even by experienced developers who have simply not considered the implications of variable references.

What does this have to do with React? React has an intelligent way of saving processing time to boost performance: If a component’s props and state have not changed, then the output of render must not have changed either. Clearly, if all things are equal, nothing has changed. If nothing has changed, render must return the same output, so let’s not bother executing it. This is what makes React fast. It only renders as needed.

React determines if its props and state are equal by comparing them with the == operator the same way JavaScript does. React does not use shallow or deep comparison on objects to determine if they are equal. Shallow comparison is a term used to describe comparing each key-value pair of an object, as opposed to comparing the memory address. Deep comparison goes one step further and if any of the values in the key-value pair are also objects, it compares those key-value pairs as well, ad nauseam. React does neither: it merely checks if the references are the same.

If you were to change a component’s prop from { x: 1 } to another object { x: 1 } , React will re-render because those two objects do not reference the same location in memory. If you were to change a component’s prop from object1 (from above) to object3 , React would not re-render, because those two objects are the same reference.

In JavaScript, functions are handled the same way. If React receives an identical function with a different memory address, it will re-render. If React receives the same function reference, it will not.

This is an unfortunately common scenario I come across during code review:

This is a pretty straightforward component. There’s a button which alerts when clicked. Instructions tell you whether or not you should click it, which is controlled by the do={true} or do={false} prop of SomeComponent .