useRef is a react hook. That lets you reference a value that is not needed for rendering
The react useRef returns a mutable object with a 'current' property. This Object remains persistent throughout the lifecycle of a component.
You can store data in this object and the data persists across re renders.
In another words, useRef returns a single current Object with an initial value that you provide, on the next renders the useRefs return the same current property with the data that you provided.
Dead Simple Chat allows you to easily add Chat to any React Application using powerful Javascript Chat SDK.
You can change its current property to store data and read it later. This might remind you of state but there is a differnce here. State causes the component to re render but useRef does not trigger a re-render
example of a useRef
function handleStartClick() {
const intervalId = setInterval(() => {
// ...
}, 1000);
intervalRef.current = intervalId;
}refs are perfect for storing values that do not affect the visual output of a component. Because change in current property of a ref does not cause the component to re render
Let us take an example of an intervalId that you might want to store and retrieve it later.
To update the ref you need to manually change its property.
function handleStopClick() {
const intervalId = intervalRef.current;
clearInterval(intervalId);
}By using a ref you get
- The information stored is local to each copy of the component
- changing the information does not trigger a re render (unlike state variable which do trigger a re render)
- store information between re render (unlike regular variables, which reset on re render)
To choose between useRef and useState keep in mind that the use ref does not trigger a re render and the useState does trigger it. So, it might not be a good idea to store UI related information in useRef
import { useRef } from "react";
export default function Counter() {
let ref = useRef(0);
function handleClick() {
ref.current = ref.current + 1;
alert("You clicked the button " + ref.current + "Times");
}
return <button onClick={handleClick}>Click the button!</button>;
}
This component Counter uses a ref to keep track of how many times the user has pressed the button

Let us consider another example:
Here we have created a Stop Watch with start and stop button. User can start the timer and stop the Stop Watch.
In this example we will use both useState and useRef as a means to differentiate their uses
import { useState, useRef } from "react";
export default function Stopwatch() {
const [startTime, setStartTime] = useState(null);
const [now, setNow] = useState(null);
const intervalRef = useRef(null);
function handleStart() {
setStartTime(Date.now());
setNow(Date.now());
clearInterval(intervalRef.current);
intervalRef.current = setInterval(() => {
setNow(Date.now());
}, 10);
}
function handleStop() {
clearInterval(intervalRef.current);
}
let secondsPassed = 0;
if (startTime != null && now != null) {
secondsPassed = (now - startTime) / 1000;
}
return (
<>
<h1>Time passed: {secondsPassed.toFixed(3)}</h1>
<button onClick={handleStart}>Start Timer</button>
<button onClick={handleStop}>Stop Timer</button>
</>
);
}
Here we have the StartTime and now variables that are state variables because they are used for rendering.
intervalRef is a ref used to store ID returned by setInterval
handleStart
handleStart function when called sets the StartTime and now
variable to current time and clears any existing intervalRef value
Creates a new Interval with setInterval function and sets the intervalRef value to current time.
HandleStop
handlestop Clears the interRef with the clearInterval function and calculate the time that has passed.
lastly we render the Stopwatch component.
Dead Simple Chat allows you to easily add Chat to any React Application using powerful Javascript Chat SDK.
Use-cases for useRefs
Dead Simple Chat allows you to easily add Chat to any React Application using powerful Javascript Chat SDK.
- Accessing DOM elements:
Userefsallow us to store DOM and manipulate DOM elements. That allows us to access the elements properties without usingstateorporps - Storing Prev values of state or props: Sometimes you need to access the previous value of state or a prop. You can store that value in a ref and access it later on
- Storing values of Instance variable: Instance variables are specific to a components instance and do not store the data that affects the components render. Thus their values can be easily stored in a ref
Dead Simple Chat allows you to easily add Chat to any React Application using powerful Javascript Chat SDK.
How to manipulate DOM elements with a ref
Manipulating the DOM with React useRef is pretty easy. Use the useRef hook to create a reference to the DOM element that you want to manipulate, then access its properties and methods without having the component to re render
lets learn more in detail
- Declare a
refobject with a initial value of null
import { useRef } from 'react';
function MyComponent() {
const inputRef = useRef(null);
// ...
}The DOM node that you want to manipulate. Pass the ref object as a attribute to the JSX like so
// ...
return <input ref={inputRef} />;Once the DOM node is rendered on the screen by React. The DOM node will be set to the current property of the ref Object. Now you can access the DOM node and its properties and methods
In the above example you can access the input property's DOM node and call its methods like focus()
function handleCLick(){
inputRef.current.focus();
}Note: The react will set the current property of the inputRef to null once the DOM node is removed from the screen.
Dead Simple Chat allows you to easily add Chat to any React Application using powerful Javascript Chat SDK.
Examples of manipulating DOM with useRef
- Clicking the button focuses the input
import { useRef } from 'react';
export default function Form() {
const inputRef = useRef(null);
function handleClick() {
inputRef.current.focus();
}
return (
<>
<input ref={inputRef} />
<button onClick={handleClick}>
Focus the input
</button>
</>
);
}

- we are importing
useReffrom react then - we are creating a function named form
- we are declaring a const
inputRefand setting it touseRef(null) - then we are creating a handleClick function and then calling the
focuson theinputRefcurrent property - on the return statement we are assigning the
inputRefto the button element - thus the button elements props and methods can be callled on the inputRef and we are calling the
focusmethod above on the inputRef iteself
2. Scrolling an image into view
import { useRef } from 'react';
export default function CatFriends() {
const listRef = useRef(null);
function scrollToIndex(index) {
const listNode = listRef.current;
// This line assumes a particular DOM structure:
const imgNode = listNode.querySelectorAll('li > img')[index];
imgNode.scrollIntoView({
behavior: 'smooth',
block: 'nearest',
inline: 'center'
});
}
return (
<>
<nav>
<button onClick={() => scrollToIndex(0)}>
Tom
</button>
<button onClick={() => scrollToIndex(1)}>
Maru
</button>
<button onClick={() => scrollToIndex(2)}>
Jellylorum
</button>
</nav>
<div>
<ul ref={listRef}>
<li>
<img
src="https://placekitten.com/g/200/200"
alt="Tom"
/>
</li>
<li>
<img
src="https://placekitten.com/g/300/200"
alt="Maru"
/>
</li>
<li>
<img
src="https://placekitten.com/g/250/200"
alt="Jellylorum"
/>
</li>
</ul>
</div>
</>
);
}
We are using the useRef hook (listRef) to reference a list of cat images in the CatFriends component.
This reference allows the user to scroll quickly a specific cat by pressing a button.
we create a scrollToIndex function
The scrollToIndex takes index as an argument and scrolls to the corresponding index from the list
First it retrieves the DOM element using the listRef.current property, then finds the image from the DOM element using queryselector('li>img')
This line assumes a particular DOM structure specifically there is an img inside of an li tag
Then scrolls the page to the selected img DOM element using scrollIntoView()
Then render theCatFriends component with three buttons each representing a cat.
Dead Simple Chat allows you to easily add Chat to any React Application using powerful Javascript Chat SDK.
Avoid Recreating the ref contents
React saves the initial value of a ref and ignores it in re renders.
function Video() {
const playerRef = useRef(new VideoPlayer());
// ...In the above example new VideoPlayer() is only used for the initial render, and you are calling this function on every render. This is wasteful if you are creating expensive objects
To solve the you can initialize the ref like this
function Video() {
const playerRef = useRef(null);
if (player.current === null){
playerRef.current = new VideoPlayer();
}first set the ref to null then only create the VideoPlayer if the ref is null. This ensures that the VideoPlayer is only created once.
If VideoPlayer is an expensive resource, creating VideoPlayer once and using it again will save resources
Normally it is not recommended to change a ref during rendering but in this case its ok because we the result is going to be the same.
Dead Simple Chat allows you to easily add Chat to any React Application using powerful Javascript Chat SDK.
Pitfalls of using inputRefs
- Do NOT read or write
ref.currentduring rendering - You can read or write from event handlers or effects instead
- If you have to read or write something during rendering
useStateinstead
Dead Simple Chat allows you to easily add Chat to any React Application using powerful Javascript Chat SDK.
Conclusion
In this article we learnt about the react useRef. We used examples to better understand what `useRef` is and what is the difference between useRef and useState
useRef does not re render the component whereas useState does re render the component.
Both can store properties and data inside of them. The data does not clear with DOM or component re render and you have to manually clear the data
thank you for reading.
Dead Simple Chat allows you to easily add Chat to any React Application using powerful Javascript Chat SDK.