Stop Unnecessary React Re‑renders: Cache Event Handlers and Master Reference Equality

This article explains how JavaScript reference equality for objects and functions affects React's shallow prop and state comparison, shows common pitfalls that cause needless re‑renders, and provides practical techniques—such as defining functions outside components and caching event listeners—to dramatically improve rendering performance.

21CTO
21CTO
21CTO
Stop Unnecessary React Re‑renders: Cache Event Handlers and Master Reference Equality

In JavaScript, objects and functions are compared by reference, not by their content. Two identical function declarations create distinct objects in memory, so functionOne === functionTwo is false, while assigning one variable to another copies the reference, making them equal.

const functionOne = function() { alert('Hello world!'); };
const functionTwo = function() { alert('Hello world!'); };
functionOne === functionTwo; // false

The same principle applies to objects: each literal creates a new memory address, so object1 === object2 is false, but object3 = object1 makes them identical references.

const object1 = {};
const object2 = {};
const object3 = object1;
object1 === object2; // false
object1 === object3; // true

React optimizes rendering by performing a shallow comparison of props and state. If the references have not changed, React assumes the output is unchanged and skips re‑rendering. Therefore, passing a new function or a newly created object—even with identical content—forces React to re‑render.

Example: a component that creates an inline onClick handler inside render generates a new function on every render, causing the child Button to re‑render even when nothing else changed.

class SomeComponent extends React.PureComponent {
  render() {
    return (
      <div>
        {this.instructions}
        <Button onClick={() => alert('!')} />
      </div>
    );
  }
}

Moving the handler outside the component preserves the same reference across renders, preventing unnecessary updates.

const createAlertBox = () => alert('!');
class SomeComponent extends React.PureComponent {
  render() {
    return (
      <div>
        {this.instructions}
        <Button onClick={createAlertBox} />
      </div>
    );
  }
}

When a handler must access component data, define it as a class method and pass the bound reference, or use an arrow property to keep the same reference.

class SomeComponent extends React.PureComponent {
  createAlertBox = () => {
    alert(this.props.message);
  };
  render() {
    return (
      <div>
        {this.instructions}
        <Button onClick={this.createAlertBox} />
      </div>
    );
  }
}

For dynamic lists where each item needs its own click handler, cache handlers keyed by a unique identifier (e.g., the item’s text). The first time a key is encountered, create the function and store it; subsequent renders reuse the same reference.

class SomeComponent extends React.PureComponent {
  clickHandlers = {};
  getClickHandler(key) {
    if (!Object.prototype.hasOwnProperty.call(this.clickHandlers, key)) {
      this.clickHandlers[key] = () => alert(key);
    }
    return this.clickHandlers[key];
  }
  render() {
    return (
      <ul>
        {this.props.list.map(item => (
          <li key={item.text}>
            <Button onClick={this.getClickHandler(item.text)} />
          </li>
        ))}
      </ul>
    );
  }
}

This caching strategy ensures that re‑rendering the component does not create new functions, keeping the Button children stable and improving performance. Be careful not to use array indices as keys, because reordering or removing items can cause stale cached handlers to fire with the wrong data.

English translation by Charles Stover, source: http://www.zcfy.cc/article/cache-your-react-event-listeners-to-improve-performance
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

frontendperformanceJavaScriptReactevent-handlingReference Equality
21CTO
Written by

21CTO

21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.