Why to use refs instead of IDs

October 21st, 2015
Updated: January 27th, 2018

Let's start by assuming that you went ahead and used an ID to access one of your elements in a React component. What could happen? Maybe your code looks like this:

class IdComponent extends React.Component {
  onFocus() {
    document.getElementById("myInput").setAttribute("class", "highlight");
  }

  onBlur() {
    document.getElementById("myInput").setAttribute("class", "");
  }

  render() {
    return (
      <div>
        <input
          id="myInput"
          onFocus={this.onFocus.bind(this)}
          onBlur={this.onBlur.bind(this)}
        />
      </div>
    );
  }
}

This would actually work. At first. Here's a demo. Tap the input field to see the highlight:

The Reusability Problem

The problem you'll encounter is with re-usability. Here's a demo of what happens when you try to create that same component multiple times. Tap through the input fields to see what happens.

So what did happen? You created multiple objects with the same ID. When any of the components asks for the element with ID myInput, the browser hands back the first one. That's why only the first <input> highlights, no matter which one you focus on.

The Solution: refs

Here's the updated component, using refs instead of IDs this time.

class RefComponent extends React.Component {
  onFocus() {
    this.myInput.setAttribute("class", "highlight");
  }

  onBlur() {
    this.myInput.setAttribute("class", "");
  }

  render() {
    return (
      <div>
        <input
          ref={input => {
            this.myInput = input;
          }}
          onFocus={this.onFocus.bind(this)}
          onBlur={this.onBlur.bind(this)}
        />
      </div>
    );
  }
}

When you use refs, you get the node rendered by this component, and you can re-use your component as much as you want. That's not guaranteed when you use IDs. Here's the working ref version:

So if you were using any IDs in your React components, go change them all to refs!