How to Update useEffect Hook in React
The useEffect hook is a fundamental tool in React for
managing side effects in functional components. This article provides a
straightforward guide on how to update and trigger the
useEffect hook using the dependency array, explaining how
to control when your effect runs, how to handle state and prop updates,
and how to properly clean up effects to prevent memory leaks.
Understanding the Dependency Array
The key to updating or re-triggering a useEffect hook is
its second argument, known as the dependency array.
React uses this array to determine whether it should skip or execute the
effect after a render.
There are three ways to configure the dependency array to control when the hook updates:
1. No Dependency Array (Updates on Every Render)
If you do not provide a dependency array, the effect will run after the initial render and after every subsequent update (render) of the component.
useEffect(() => {
console.log('This runs after every single render');
});2. Empty Dependency Array (Runs Once)
If you pass an empty array [], the effect runs exactly
once after the initial render (component mount). It will not run on
subsequent updates, even if state or props change.
useEffect(() => {
console.log('This runs only once when the component mounts');
}, []);3. Array with Dependencies (Updates on Specific Changes)
To update the effect only when specific values change, pass those values inside the dependency array. React will compare the current value of the dependency with its value from the previous render. If any value in the array has changed, the effect runs again.
const [count, setCount] = useState(0);
useEffect(() => {
console.log(`The count is now ${count}`);
}, [count]); // This effect updates only when 'count' changesHow to Handle Object and Array Dependencies
React uses shallow comparison (strict equality ===) to
detect changes in the dependency array. Because objects and arrays in
JavaScript are compared by reference rather than value, passing them
directly into the dependency array can cause the effect to run on every
render if the reference changes.
To safely update useEffect with objects or arrays, use
one of the following approaches:
- Deconstruct the object: Pass specific primitive properties into the dependency array instead of the entire object.
- Use
useMemooruseCallback: Memoize the object or function to maintain the same reference across renders unless its dependencies change.
// Deconstructing properties for the dependency array
const user = { name: "Alice", age: 30 };
useEffect(() => {
console.log(`User age changed to: ${user.age}`);
}, [user.age]); // Only triggers when 'age' changes, not the whole object referenceCleaning Up Before the Next Update
When a dependency changes and triggers an update, React runs a cleanup function (if provided) from the previous execution before running the effect again. This prevents memory leaks and stale data.
To clean up an effect, return a function from inside your
useEffect callback:
useEffect(() => {
const handleResize = () => console.log(window.innerWidth);
window.addEventListener('resize', handleResize);
// Cleanup function runs before the next update or unmount
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);