When to Use useMemo vs useRef: A Practical Guide for React Developers
By Saman Batool
June 28, 2025
React’s useMemo
and useRef
are powerful hooks that solve distinct problems in application performance and state management. Knowing when and why to use them improves your code’s efficiency and readability. Here’s a practical breakdown with examples, including real-world scenarios.
What is useMemo?
useMemo
is a React hook that memoizes the result of a function. It returns the cached value unless the specified dependencies change or the function hasn't been evaluated before. This optimizes performance by preventing repeated function calls on each render of a component.
When to Use useMemo
Use useMemo
when:
- A computationally expensive function is being re-executed unnecessarily.
- The return value of a function is used directly in rendering or as a dependency for other hooks.
Example: Avoiding Recomputations
Let’s say you need to calculate the sum of an array before rendering:
``` const numbers = [1, 2, 3, 4, 5]
const sum = useMemo(() => { let total = 0; for (let num of numbers) { total += num; } return total; }, [numbers]);
return
Here, useMemo
ensures the sum is recalculated only when numbers
changes. Without useMemo
, the calculation would run on every render.
Real-world Scenario: Calendar Grid Rendering
In a calendar application, calculating and rendering cells for each day can be computationally expensive. Using useMemo
helps optimize this process:
const cells = useMemo(() => {
return Array.from({length: 7}).map((_, dayIndex) => {
const dateNumber = calendarGrid[weekIndex][dayIndex];
const isCurrentDay =
viewingCurrentMonthAndYear && dateNumber === currentDate.getDate();
return (
<CalendarCell
key={`calendarCell:${weekIndex}:${dayIndex}`}
weekIndex={weekIndex}
dayIndex={dayIndex}
dateNumber={dateNumber}
isCurrentDay={isCurrentDay}
/>
);
});
}, [calendarGrid, weekIndex, currentDate, viewingCurrentMonthAndYear]);
What is useRef
?
useRef
is a React hook that provides a mutable container. Unlike state, changing a ref
does not trigger a component re-render.
When to Use useRef
Use useRef
when:
- You need to persist a value between renders without causing a re-render.
- Accessing DOM elements directly.
Example: Tracking Render Counts
You might want to track how many times a component has rendered:
``` const renderCount = useRef(0);
useEffect(() => { renderCount.current += 1; });
return
Here, useRef
allows you to persist and update the renderCount
without triggering additional renders.
Real-world Scenario: Scrolling in a Chat Application
In a chat interface, you might need to scroll to the latest message whenever new messages arrive. Using useRef
ensures this behavior without triggering unnecessary re-renders:
``` const messagesScrollViewRef = useRef(null); useEffect(() => { messagesScrollViewRef.current?.scrollToEnd({animated: true}); }, [messages]);
return (
Choosing Between useMemo
and useRef
Deciding whether to use useMemo
or useRef
often comes down to the specific needs of your application. Here are some general guidelines to help:
* Use useMemo
when you need to optimize calculations or prevent redundant computations. This can be especially helpful for computationally expensive operations or to avoid unnecessary renders of dependent child components.
* Use useRef
when you want to persist mutable data across renders or need direct access to a DOM element. This is ideal for managing scroll positions, focus handling, and tracking non-reactive data (such as a fetched list of items) to avoid unnecessary API requests.
To Consider
While these hooks are powerful, overusing them can complicate your code. Here are some best practices that I’ve learned:
Be cautious when using
useMemo
: While it can be powerful, addinguseMemo
unnecessarily can add complexity and should only be used when a clear performance issue justifies the optimization. Simpler computations typically don’t benefit much from memoization.Avoid using
useRef
as a state replacement:useRef
does not trigger re-rerenders when its value changes. This makes it unsuitable for managing reactive application state. Use it for non-reactive, persistent values.
Closing Thoughts
Both useMemo
and useRef
have unique strengths that can lead to a more performant and maintainable codebase. useMemo
is great for scenarios where heavy computations or derived values are needed, like optimizing grid rendering in a calendar component. useRef
excels in managing mutable references, such as ensuring a chat interface stays scrolled to the latest message or tracking render counts.
By combining these hooks effectively, you can reduce unnecessary renders and manage performance-heavy operations. Whether you’re optimizing a complex application or just starting with React, they are invaluable tools to have in your development toolkit. Happy coding!