The useRef Hook lets you store a mutable value that persists across component renders. It is commonly used to access DOM elements or keep values without causing re-renders.
- Returns an object with a .current property to hold any value
- Updating .current does not trigger a re-render
- Useful for DOM access, timers, and storing previous values
Does Not Cause Re-renders
If we tried to count how many times our application renders using the useState Hook, we would be caught in an infinite loop since this Hook itself causes a re-render.
To avoid this, we can use the useRef Hook
*Syntax *:
const refContainer = useRef(initialValue);
- useRef returns an object { current: initialValue }.
- The current property can be updated without re-rendering the component
Implementing the useRef hook
import { useState, useRef, useEffect } from 'react';
import { createRoot } from 'react-dom/client';
function App() {
const [inputValue, setInputValue] = useState("");
const count = useRef(0);
useEffect(() => {
count.current = count.current + 1;
});
return (
<>
<p>Type in the input field:</p>
<input
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
/>
<h1>Render Count: {count.current}</h1>
</>
);
}
createRoot(document.getElementById('root')).render(
<App />
);
The useRef hook is used to access DOM elements and persist values across renders without triggering re-renders.
- Accessing the DOM using useRef hook A ref created with useRef is attached to the textarea, allowing the click handler to access the DOM element and programmatically set focus.
import React, { Fragment, useRef } from 'react';
function App() {
const focusPoint = useRef(null);
const onClickHandler = () => {
focusPoint.current.value =
"The quick brown fox jumps over the lazy dog";
focusPoint.current.focus();
};
return (
<Fragment>
<div>
<button onClick={onClickHandler}>
ACTION
</button>
</div>
<label>
Click on the action button to
focus and populate the text.
</label><br />
<textarea ref={focusPoint} />
</Fragment>
);
};
export default App;
- useRef creates a reference focusPoint, which allows direct manipulation of the DOM element.
- Clicking the "ACTION" button triggers onClickHandler, which sets text in the textarea and focuses it.
- (<>...</>) is used to group multiple elements without adding extra wrappers in the DOM.
useRef() only returns one item. It returns an Object called current.
When we initialize useRef we set the initial value: useRef(0).
Tracking State Changes
The useRef Hook can also be used to keep track of previous state values.
This is because we are able to persist useRef values between renders.
Example:
Use useRef to keep track of previous state values:
import { useRef, useState, useEffect } from 'react';
import { createRoot } from 'react-dom/client';
function App() {
const [inputValue, setInputValue] = useState("");
const previousInputValue = useRef("");
useEffect(() => {
previousInputValue.current = inputValue;
}, [inputValue]);
return (
<>
<input
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
/>
<h2>Current Value: {inputValue}</h2>
<h2>Previous Value: {previousInputValue.current}</h2>
</>
);
}
createRoot(document.getElementById('root')).render(
<App />
);
This time we use a combination of useState, useEffect, and useRef to keep track of the previous state.
In the useEffect, we are updating the useRef current value each time the inputValue is updated by entering text into the input field.
Top comments (1)
Good Start!