I’ve been building applications with Python and JavaScript for over a decade now.
During my early years, I often struggled with the “React way” of doing things when I needed to touch the DOM directly.
It felt like trying to bypass the virtual DOM, which is exactly what a Ref does.
In this guide, I will share my experience on how to use React class component refs effectively.
What is a React Class Component Ref?
A Ref is simply a way to access a DOM node or a React element created in the render method.
In my experience, you should only use them when you absolutely need to manage focus, trigger animations, or integrate with third-party libraries.
Think of it as an “escape hatch” from the standard React data flow.
Method 1: Use React.createRef()
This is the most common method I use in modern class-based applications.
I find it very clean because you initialize the ref in the constructor and then attach it to an element.
Imagine you are building a secure login form for a financial app based in New York. You want the “Social Security Number” field to focus automatically when the page loads.
Here is the full code:
import React, { Component } from 'react';
class SSNLoginField extends Component {
constructor(props) {
super(props);
// I create the ref here to use it throughout the component
this.ssnInputRef = React.createRef();
}
componentDidMount() {
// I use the .current property to access the actual DOM node
this.ssnInputRef.current.focus();
console.log("SSN Input focused on mount - Manhattan Secure Portal");
}
render() {
return (
<div style={{ padding: '20px', textAlign: 'center' }}>
<h2>Member Login</h2>
<label>Enter SSN: </label>
<input
type="text"
ref={this.ssnInputRef}
placeholder="000-00-0000"
/>
<button onClick={() => alert('Processing Login...')}>Login</button>
</div>
);
}
}
export default SSNLoginField;You can see the output in the screenshot below.

In this example, this.ssnInputRef.current gives me direct access to the input tag.
Method 2: Use Callback Refs
Before createRef() was introduced, I relied heavily on Callback Refs. Instead of passing a ref object, you pass a function that receives the DOM element as an argument.
I still use this today when I need more fine-grained control over when the ref is set or unset.
Let’s look at a shipping calculator example for a logistics company in Seattle.
import React, { Component } from 'react';
class ShippingCalculator extends Component {
constructor(props) {
super(props);
this.zipCodeRef = null;
// This callback function sets the local variable to the element
this.setZipCodeRef = (element) => {
this.zipCodeRef = element;
};
}
handleCalculate = () => {
if (this.zipCodeRef) {
const zip = this.zipCodeRef.value;
alert(`Calculating shipping rates for Seattle area: ${zip}`);
}
};
render() {
return (
<div style={{ margin: '50px' }}>
<h3>Seattle Express Shipping</h3>
<input
type="text"
ref={this.setZipCodeRef}
placeholder="Enter Zip Code"
/>
<button onClick={this.handleCalculate}>Get Rates</button>
</div>
);
}
}
export default ShippingCalculator;You can see the output in the screenshot below.

I like this method because I don’t have to deal with the .current property; I just access this.zipCodeRef directly.
Method 3: Use String Refs (The Legacy Way)
You might encounter “String Refs” in older legacy projects. In this style, you just give the ref a string name like ref=”myInput”.
I highly recommend avoiding this for new projects, as it has some performance issues and is considered deprecated.
However, if you are maintaining an old codebase for a tech firm in Austin, you might see this:
import React, { Component } from 'react';
class LegacyProfile extends Component {
handleUpdate = () => {
// Accessing via this.refs
const name = this.refs.userName.value;
alert(`Updating profile for: ${name}`);
};
render() {
return (
<div>
<h4>User Profile (Legacy System)</h4>
<input type="text" ref="userName" defaultValue="John Doe" />
<button onClick={this.handleUpdate}>Update</button>
</div>
);
}
}
export default LegacyProfile;You can see the output in the screenshot below.

Even though it works, I always try to refactor these to createRef() whenever I have the chance.
When Should You Use Refs?
I have found that developers often overuse refs when they should be using state.
If you can do it with props and state, do it that way first.
Only use refs for:
- Managing focus, text selection, or media playback.
- Triggering imperative animations.
- Integrating with third-party DOM libraries (like D3.js or Google Maps).
Best Practices for Refs in Class Components
I’ve learned a few hard lessons about refs over the last 10 years.
First, never use refs for anything that can be done declaratively.
If you find yourself using a ref to “reach inside” a child component to change its style, you’re likely doing it wrong.
Second, always remember that createRef() returns an object with a current property.
I can’t tell you how many times I’ve forgotten to add .current and wondered why my code wasn’t working!
Using refs is a powerful tool in your React toolkit.
While the industry is moving toward Functional Components and Hooks, knowing how to handle refs in class components is vital for any serious developer.
I hope this tutorial helps you understand how to manage DOM elements in your React applications.
You may also like to read:
- How to Use React Pivot Table
- How to Destructure Props in React Functional Components
- How to Use Lazy Loading Component in React
- React Force Reload Component

I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.