In React.js, the useRef hook provides a way to create mutable references to elements or values that persist across renders without causing re-renders. This chapter explores useRef in depth, covering basic usage, advanced techniques, and practical examples to demonstrate its versatility in React applications.
The useRef
hook is primarily used to persist values across renders without causing re-renders. It returns a mutable ref object whose .current
property is initialized to the passed argument (initialValue
). The .current
property persists between renders and can hold any value.
Let’s begin with a basic example to understand how useRef
works.
import React, { useRef } from 'react';
function App() {
const inputRef = useRef(null);
const focusInput = () => {
inputRef.current.focus();
};
return (
);
}
export default App;
useRef(null)
creates a mutable ref object inputRef
with an initial value of null
.input
element uses ref={inputRef}
to assign the ref to the input.focusInput
function uses inputRef.current
to access the DOM node and calls .focus()
to focus the input when the button is clicked.When you run this application, you’ll see an input field and a button labeled “Focus Input”. Clicking the button will focus the input field due to the use of inputRef.current.focus()
.
You can use useRef
to store previous values or states without causing re-renders.
import React, { useState, useEffect, useRef } from 'react';
function App() {
const [count, setCount] = useState(0);
const prevCountRef = useRef();
useEffect(() => {
prevCountRef.current = count;
});
const prevCount = prevCountRef.current;
return (
Current Count: {count}
Previous Count: {prevCount !== undefined ? prevCount : 'N/A'}
);
}
export default App;
prevCountRef
is initialized using useRef()
.useEffect
hook, prevCountRef.current
is updated with the current count
value whenever count
changes.prevCount
retrieves the previous count from prevCountRef.current
and displays it.count
state, and the previous count is updated accordingly.Initially, “Current Count: 0” and “Previous Count: N/A” are displayed. Clicking the “Increment” button updates the current count and shows the previous count.
useRef
for DOM MeasurementsYou can use useRef
to access DOM measurements or properties directly.
import React, { useRef } from 'react';
function App() {
const divRef = useRef(null);
const getDivDimensions = () => {
if (divRef.current) {
const { width, height } = divRef.current.getBoundingClientRect();
alert(`Width: ${width}, Height: ${height}`);
}
};
return (
Resize Me
);
}
export default App;
divRef
is created using useRef()
.div
element uses ref={divRef}
to assign the ref to the div
.getDivDimensions
accesses divRef.current
to retrieve the getBoundingClientRect()
values (width and height) of the div
when the button is clicked.When you run this application, you’ll see a resizable div
element with a button labeled “Get Dimensions”. Clicking the button will alert the width and height of the div
element.
You can use useRef
for imperative DOM manipulation, such as triggering animations or managing focus.
import React, { useRef } from 'react';
function App() {
const buttonRef = useRef(null);
const animateButton = () => {
if (buttonRef.current) {
buttonRef.current.classList.add('animate');
setTimeout(() => {
buttonRef.current.classList.remove('animate');
}, 1000);
}
};
return (
);
}
export default App;
buttonRef
is created using useRef()
.button
element uses ref={buttonRef}
to assign the ref to the button
.animateButton
function accesses buttonRef.current
to add and remove the animate
class for CSS animations when the button is clicked.When you run this application, you’ll see a button labeled “Animate Me”. Clicking the button will trigger a CSS animation defined by the animate
class.
In this example, we will create a form with multiple input fields and use useRef
to manage focus between these inputs. This can be useful for improving user experience by automatically focusing the next input when certain conditions are met.
import React, { useRef } from 'react';
function App() {
const firstNameRef = useRef(null);
const lastNameRef = useRef(null);
const emailRef = useRef(null);
const handleFirstNameKeyPress = (event) => {
if (event.key === 'Enter') {
lastNameRef.current.focus();
}
};
const handleLastNameKeyPress = (event) => {
if (event.key === 'Enter') {
emailRef.current.focus();
}
};
const handleSubmit = (event) => {
event.preventDefault();
alert('Form Submitted!');
};
return (
Form with Managed Focus
);
}
export default App;
firstNameRef
, lastNameRef
, emailRef
) using useRef(null)
and assign them to the input fields.onKeyPress
events on the first two input fields. If the Enter key is pressed, the focus shifts to the next input field using ref.current.focus()
.When you run this application, you will see a form with three input fields (First Name, Last Name, and Email). Pressing Enter in the First Name field will automatically focus the Last Name field, and pressing Enter in the Last Name field will focus the Email field. Submitting the form will show an alert.
In this example, we will create a timer that can be started, stopped, and reset. We will use useRef
to store the timer ID to manage the interval properly.
import React, { useState, useRef } from 'react';
function App() {
const [seconds, setSeconds] = useState(0);
const timerRef = useRef(null);
const startTimer = () => {
if (!timerRef.current) {
timerRef.current = setInterval(() => {
setSeconds((prevSeconds) => prevSeconds + 1);
}, 1000);
}
};
const stopTimer = () => {
if (timerRef.current) {
clearInterval(timerRef.current);
timerRef.current = null;
}
};
const resetTimer = () => {
stopTimer();
setSeconds(0);
};
return (
Timer
Seconds: {seconds}
);
}
export default App;
useState
to keep track of the number of seconds elapsed.timerRef
using useRef(null)
to store the timer ID returned by setInterval
.startTimer
sets up an interval that increments the seconds state every second. It checks if timerRef.current
is null to avoid multiple intervals.stopTimer
clears the interval if it exists and resets timerRef.current
to null.resetTimer
stops the timer and resets the seconds state to zero.When you run this application, you will see a timer display with buttons to start, stop, and reset the timer. Clicking “Start” begins the timer, incrementing the seconds count every second. Clicking “Stop” pauses the timer, and clicking “Reset” stops the timer and resets the count to zero.
The useRef hook in React provides a way to persist mutable values across renders without causing re-renders. It is useful for accessing DOM elements, managing previous states, or imperative DOM manipulations. By understanding and effectively using useRef, you can enhance your React applications with improved performance and maintainability. This chapter covered basic usage, practical examples, and advanced techniques to give you a comprehensive understanding of useRef in React.js.Happy coding !❤️