The useRef hook is useful for tracking values across renders without causing re-renders themselves. One common use case is to detect the first render of a component and perform logic only after that, without triggering actions during the initial render.
Here's how it works:
Step 1: Set up a useRef to track the component's mount state.
const isMounted = useRef(false);
This initializes a ref variable isMounted with a value of false, meaning the component has not yet been rendered.
Step 2: Add a condition in useEffect to handle the initial render.
useEffect(() => {
if (!isMounted.current) {
// If the component is rendering for the first time, set isMounted to true and exit early
isMounted.current = true;
return;
}
// Log message only after the component has re-rendered
console.log('component re-rendered');
}, [value]);
- The
if (!isMounted.current)checks if the component is being rendered for the first time. - On the first render,
isMounted.currentisfalse, so it gets set totrueand the effect exits. - On subsequent renders,
isMounted.currentistrue, so theconsole.logstatement runs.
Full Example:
import { useRef, useState, useEffect } from 'react';
const App = () => {
const [value, setValue] = useState(0);
const isMounted = useRef(false);
useEffect(() => {
if (!isMounted.current) {
// console.log('component initial render');
isMounted.current = true;
return;
}
console.log('component re-rendered');
}, [value]);
return (
<div>
<h1>value: {value}</h1>
<button onClick={() => setValue(value + 1)} className="btn">
Increase
</button>
</div>
);
};
export default App;
Explanation:
- On the initial render, the
useEffectwill not log anything because it exits early. - On every subsequent render triggered by the
valuestate change, it will logcomponent re-rendered.
Why use this pattern?
- It’s helpful when you need to avoid running certain logic (like API calls, event listeners, etc.) on the initial render but want to execute it on re-render after that.

Top comments (0)