What Are React Refs?
In React, ref stands for reference. ref is a special attribute in React that allows you to directly reference an element or component in the DOM (Document Object Model)
React controls everything through state and props, but sometime when you need to directly touch the DOM, So you can use ref because ref provide indispensable way to interact with DOM.
With refs, you can bypass the typical React data flow and directly manipulate elements.
To create a ref in a React component, you can use the React.createRef() method (for class components) or the useRef hook (for functional components).
Example of Creating a Ref
import React, { useRef } from 'react';
function AutoFocusInput() {
const textInputRef = useRef(null);
const triggerFocus = () => {
if (textInputRef.current) {
textInputRef.current.focus(); // Focus the input element
}
};
return (
<div>
<input type="text" ref={textInputRef} placeholder="Type something..." />
<button onClick={triggerFocus}>Set Focus</button>
</div>
);
}
// Example usage
<AutoFocusInput />
In this example:
- textInputRef is a ref that holds a reference to the input DOM element.
- The triggerFocus function accesses the input element using textInputRef.current and sets the focus on the input field when the “Set Focus” button is clicked.
When and Why to Use Refs in React
When you want to access a DOM Element or child component directly, So you can use the ref.
1) Managing Focus:
When you want to programmatically set focus in input field. automatically place the typing cursor inside input box without use click on it, you use React Ref to “manage focus”.
🧠Example Situation: Imagine you open a popup form (model) on your website or project, and first input box (like “Name Field”) to be automatically ready for typing.
✅ So instead of asking the user to click on the input field, you use a ref to do this automatically when the modal open.
2) Triggering Animations:
Sometimes you want to run custom animations (like sliding, bouncing, fading) that are not easy to control using React’s state (useState) or props. you can use refs to directly access and animate the DOM element manually using JavaScript or libraries like GSAP or anime.js.
🧠Example Scenario:
Imagine you want a box to slide or bounce when a button is clicked, but you don’t want to use complex state logic or re-renders.
In this case, you use useRef to grab the element and apply animation directly.
💻 Real-Life Example:
import React, { useRef } from 'react';
function BounceBox() {
const boxRef = useRef(null);
const animateBox = () => {
if (boxRef.current) {
boxRef.current.style.transform = "translateY(-20px)";
setTimeout(() => {
boxRef.current.style.transform = "translateY(0)";
}, 300);
}
};
return (
<div>
<div
ref={boxRef}
style={{
width: "100px",
height: "100px",
backgroundColor: "skyblue",
transition: "transform 0.3s ease",
marginBottom: "10px",
}}
/>
<button onClick={animateBox}>Bounce</button>
</div>
);
}
✅ Result:
When you click on the “Bounce” button, the box jumps up and comes back, all handled working using a ref without any React state.
3) Accessing DOM Elements Directly:
in React, you need to directly interact with HTML elements, like checking how far the user has scrolled, measuring the size of element, or integrating non-React libraries (like sliders, charts, maps, etc.).
In these case, you can not always rely on React’s state and props system, so you use can use Ref to access the DOM element and perform those tasks.
💻 Real-Life Example: Scroll Position
import React, { useRef } from 'react';
function ScrollChecker() {
const scrollBoxRef = useRef(null);
const handleCheckScroll = () => {
const scrollTop = scrollBoxRef.current.scrollTop;
alert(`Scrolled: ${scrollTop}px`);
};
return (
<div>
<div
ref={scrollBoxRef}
style={{
height: "100px",
overflowY: "scroll",
border: "1px solid black",
marginBottom: "10px",
}}
>
<div style={{ height: "300px" }}>
Scroll this content
</div>
</div>
<button onClick={handleCheckScroll}>Check Scroll Position</button>
</div>
);
}
✅ Result:
- You scroll the box.
- Click the button.
- how many pixels you’ve scrolled by accessing the DOM by the ref.
4) Handling Form Data:
In React, it’s common to use useState to store and update input values.
But if you have many inputs or you want to avoid re-rendering the component every time a user types, So you can use useRef instead of that.
With useRef, you can access the current value of input directly from the DOM, without triggering re-renders on every keystroke.
🧠Why use useRef instead of useState?
useState | useRef |
---|---|
Triggers re-render on each update | Does not trigger re-render |
Good for live UI updates | Good for simple data retrieval |
More code for large forms | Cleaner for large forms |
💻 Example:
import React, { useRef } from 'react';
function SimpleForm() {
const nameInputRef = useRef(null);
const handleSubmit = (e) => {
e.preventDefault();
alert(`Name entered: ${nameInputRef.current.value}`);
};
return (
<form onSubmit={handleSubmit}>
<input type="text" ref={nameInputRef} placeholder="Enter your name" />
<button type="submit">Submit</button>
</form>
);
}
✅ Result:
- You type your name.
- Click Submit.
- It showing a alert with the entered name and no state was used!
5) Interacting with Third-Party Libraries:
When you use external libraries (like Chart.js, Google Maps, Swiper.js, jQuery plugins, etc.) inside your React app, So many of them expect you to give them access to a real HTML element (DOM node), not React’s virtual DOM.
React hides the real DOM behind its virtual DOM, you need useRef to get direct access to that HTML element and pass it to the library.
How to Create and Use Refs
In React, refs can be created in both functional and class components. Here’s a Explanation for each approach:
Creating Refs in Functional Components (with useRef)
In functional components, you use the useRef hook to create refs. The useRef hook returns a mutable object that persists throughout the component’s lifecycle. This object has a .current property where the reference is stored.
import React, { useRef } from 'react';
function CustomVideoPlayer() {
const playerRef = useRef(null);
const handlePlay = () => {
if (playerRef.current) {
playerRef.current.play();
}
};
const handlePause = () => {
if (playerRef.current) {
playerRef.current.pause();
}
};
return (
<div>
<video
ref={playerRef}
src="sample-video.mp4"
width="360"
height="240"
controls={false}
/>
<div>
<button onClick={handlePlay}>Start Video</button>
<button onClick={handlePause}>Stop Video</button>
</div>
</div>
);
}
export default CustomVideoPlayer;
In this example:
- playerRef refers to the video element.
- The handlePlay and handlePause functions use playerRef.current to directly control the video playback.
Creating Refs in Class Components (with React.createRef)
In class components, you can create refs using React.createRef(). This method returns a ref object that can be attached to a DOM element or component.
import React, { Component } from 'react';
class InputBox extends Component {
constructor(props) {
super(props);
this.inputElementRef = React.createRef();
}
triggerFocus = () => {
if (this.inputElementRef.current) {
this.inputElementRef.current.focus();
}
};
render() {
return (
<div>
<input type="text" ref={this.inputElementRef} placeholder="Type something..." />
<button onClick={this.triggerFocus}>Set Focus</button>
</div>
);
}
}
export default InputBox;
In this example:
- inputElementRef holds a reference to the <input> element.
- The triggerFocus method uses inputElementRef.current to bring focus to the input field when the button is clicked.
Practical Applications of Refs in React
Here are some common real-world applications of refs in React:
Focusing an Input Field
the cursor should automatically appear inside the input box
import React, { useRef, useEffect } from 'react';
function AutoFocusField() {
const fieldRef = useRef(null);
useEffect(() => {
if (fieldRef.current) {
fieldRef.current.focus();
}
}, []);
return <input type="text" ref={fieldRef} placeholder="Enter something..." />;
}
export default AutoFocusField;
Here, useEffect with empty dependency array ensures the input field is focused immediately.
Handling Form Data Without State
In some cases, refs are used to read input data without updating the state for each keystroke.
import React, { useRef } from 'react';
function SimpleForm() {
const inputRef = useRef(null);
const onFormSubmit = (event) => {
event.preventDefault();
const enteredName = inputRef.current.value;
alert(`Entered Name: ${enteredName}`);
};
return (
<form onSubmit={onFormSubmit}>
<label htmlFor="username">Your Name:</label>
<input id="username" type="text" ref={inputRef} placeholder="Full name" />
<button type="submit">Send</button>
</form>
);
}
export default SimpleForm;
Accessing Scroll Position
Refs are helpful when you need to track the scroll position of element.
import React, { useRef } from 'react';
function MessageViewer() {
const containerRef = useRef(null);
const handleScrollDown = () => {
if (containerRef.current) {
containerRef.current.scrollTop = containerRef.current.scrollHeight;
}
};
return (
<div>
<div
ref={containerRef}
style={{
height: '160px',
overflowY: 'auto',
border: '2px solid #444',
padding: '10px',
}}
>
{/* Long content goes here */}
<p>Line 1</p>
<p>Line 2</p>
<p>Line 3</p>
<p>Line 4</p>
<p>Line 5</p>
<p>Line 6</p>
<p>Line 7</p>
<p>Line 8</p>
<p>Line 9</p>
<p>Line 10</p>
</div>
<button onClick={handleScrollDown}>Go to Bottom</button>
</div>
);
}
export default MessageViewer;
In this example, the handleScrollDown function scrolls the content to the bottom of the container when the “Go to Bottom” button is clicked.