Understanding useEffect in React (and Next.js) – A Beginner’s Guide
If you’re just starting out with React or Next.js, one of the first Hooks you’ll encounter is useEffect. At first, it may look a bit mysterious, but don’t worry — this guide will break it down step by step in plain English.
What is useEffect?
In React, useEffect is a Hook used to handle side effects in your components.
A side effect means anything that happens outside the normal process of rendering UI. For example:
- Fetching data from an API
- Listening to user events (like scrolling or resizing the window)
- Starting or cleaning up timers
- Interacting with localStorage or other browser APIs
In short: useEffect lets you run code after your component renders.
Basic Example
import { useEffect, useState } from "react";
export default function MyComponent() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log("Component rendered!");
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
}
What happens here?
- The first time the component appears, the message "Component rendered!" is logged.
- Every time count changes, the component re-renders — and the effect runs again.
The Dependency Array
useEffect takes a second argument: the dependency array. This controls when the effect should run.
useEffect(() => {
console.log("Runs only when `count` changes");
}, [count]);
- [] → Runs only once (on mount). Useful for initialization.
- [count] → Runs when count changes.
- (no array) → Runs after every render (not recommended unless you really need it).
Cleaning Up Effects
Some effects need cleanup, like event listeners or timers. You can return a function inside useEffect to clean things up.
useEffect(() => {
const timer = setInterval(() => {
console.log("Tick...");
}, 1000);
// Cleanup when component unmounts or before running again
return () => {
clearInterval(timer);
console.log("Timer cleared!");
};
}, []);
Special Notes for Next.js
Because Next.js does server-side rendering (SSR), it’s important to know:
- useEffect only runs on the client-side, never on the server.
- That means you can safely use browser-only features (like window or localStorage) inside useEffect.
Key Takeaways
- useEffect = run side effects after render.
- The dependency array controls when it runs.
- Return a function to clean up things like timers or event listeners.
- In Next.js, it only runs in the browser, not on the server.
