Introduction
When working with React, useRef is a powerful hook that allows you to access and persist values across renders without causing re-renders. This makes it an essential tool for handling DOM references, persisting state, and optimizing performance.
This article will break down useRef, explore its use cases, and demonstrate best practices for using it effectively in TypeScript projects.
Understanding useRef π₯
The useRef hook is a built-in React hook that returns a mutable object with a .current property. Unlike state variables created with useState, modifying useRef does not trigger re-renders.
Syntax
const ref = useRef<T>(initialValue);
Tis the type of the referenced value.initialValueis the initial value of.current.
Example:
import { useRef } from "react";
const inputRef = useRef<HTMLInputElement | null>(null);
Common Use Cases βοΈ
1. Accessing and Manipulating DOM Elements
A frequent use case for useRef is accessing DOM elements without triggering re-renders.
import { useRef } from "react";
const FocusInput = () => {
const inputRef = useRef<HTMLInputElement>(null);
const handleClick = () => {
inputRef.current?.focus();
};
return (
<div>
<input ref={inputRef} type="text" placeholder="Type something..." />
<button onClick={handleClick}>Focus Input</button>
</div>
);
};
export default FocusInput;
Explanation:
The
inputRefrefers to the<input>element.Calling
inputRef.current?.focus()sets focus on the input field.
2. Persisting Values Without Re-Renders
useRef is useful for persisting values that donβt trigger re-renders, such as timers, previous values, or component lifecycles.
import { useEffect, useRef, useState } from "react";
const Timer = () => {
const [count, setCount] = useState(0);
const intervalRef = useRef<NodeJS.Timeout | null>(null);
useEffect(() => {
intervalRef.current = setInterval(() => {
setCount((prev) => prev + 1);
}, 1000);
return () => {
if (intervalRef.current) clearInterval(intervalRef.current);
};
}, []);
return <p>Timer: {count} seconds</p>;
};
export default Timer;
Explanation:
The
intervalRefpersists the interval ID.It prevents unnecessary re-renders while ensuring the timer can be cleared when needed.
3. Storing Previous Values
We can use useRef to store the previous state value before a component re-renders.
import { useEffect, useRef, useState } from "react";
const PreviousValue = () => {
const [count, setCount] = useState(0);
const prevCountRef = useRef<number>(count);
useEffect(() => {
prevCountRef.current = count;
}, [count]);
return (
<div>
<p>Current: {count}</p>
<p>Previous: {prevCountRef.current}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};
export default PreviousValue;
Explanation:
prevCountRef.currentstores the previous count.Even after re-renders, it retains the previous state value.
Best Practices for useRef π―
1- Use useRef for Non-Rendering Data: Avoid using it for state management that affects UI.
2- Use TypeScript to Ensure Safety: Always define proper types to avoid null or undefined errors.
3- Remember That useRef Doesnβt Trigger Re-Renders: Update .current only when necessary.
4- Avoid Overuse: If a value needs to trigger a re-render, useState is the better option.
Conclusion β
The useRef hook is an essential tool for optimizing React applications. Whether accessing DOM elements, persisting values, or handling timers, it provides performance benefits by preventing unnecessary re-renders.
By combining useRef with TypeScript, you can write safer and more maintainable React applications.
π Connect With Me On:
π LinkedIn
π X (Twitter)
π Telegram
π Instagram
Happy Coding!
Top comments (0)