DEV Community

Sospeter Mong'are
Sospeter Mong'are

Posted on

Understanding `useEffect` in React: A Beginner-Friendly Guide

If you’re new to React, one thing that often confuses beginners is when and why to use useEffect. Let’s break it down slowly, so it makes perfect sense even if you’ve never done frontend before.


1. What is useEffect?

useEffect is a React Hook that lets you perform side effects in a component.

Side effects are things your component does that are outside rendering the UI:

  • Fetching data from an API
  • Logging to the console
  • Setting timers (setTimeout)
  • Interacting with browser APIs (like localStorage)

In plain terms:

“useEffect is a way to tell React: do this action after the component appears on the page or when something changes.”


2. When do you actually need it?

Think of useEffect as React’s way of replacing old lifecycle methods from class components:

Old React class method useEffect equivalent Typical use
componentDidMount useEffect(() => { ... }, []) Run once on page load
componentDidUpdate useEffect(() => { ... }, [dependency]) Run when a value changes
componentWillUnmount useEffect(() => { return () => {...} }, []) Clean up before component disappears

2.1 Backend Analogy

If React were a backend server:

  • useEffect(() => fetchData(), []) → “Call the database once when the request starts
  • useEffect(() => fetchData(), [userId]) → “Call the database every time the userId changes

This makes it very intuitive if you already understand API calls and triggers.


3. The Basic Syntax

useEffect(() => {
  // code you want to run
}, [dependencies]);
Enter fullscreen mode Exit fullscreen mode

Breaking it down:

  • First argument: A function containing the code you want to run (your “effect”)
  • Second argument: An array of dependencies that tells React when to run the effect

3.1 Dependency Array []

  • Empty array [] → Run once, after the component loads
  • Example:
useEffect(() => {
  console.log("Component loaded!");
}, []);
Enter fullscreen mode Exit fullscreen mode

Think of it like onPageLoad.


3.2 Dependencies [value]

  • Add values inside the array → Run every time one of these values changes
const [count, setCount] = useState(0);

useEffect(() => {
  console.log(`Count changed to: ${count}`);
}, [count]);
Enter fullscreen mode Exit fullscreen mode

Here, the effect only runs when count changes.
Backend analogy: “Re-fetch or re-run a query when this parameter changes.”


3.3 No Dependency Array

If you don’t provide a dependency array, the effect runs after every render:

useEffect(() => {
  console.log("Runs on every render!");
});
Enter fullscreen mode Exit fullscreen mode

⚠️ Be careful — this can cause infinite loops if you update state inside the effect.


4. A Real Example: Fetching Groups on Page Load

This is exactly like your GroupList component:

useEffect(() => {
  fetch("http://localhost:3000/groups", {
    headers: {
      Authorization: "Bearer TOKEN"
    }
  })
    .then((res) => res.json())
    .then((data) => setGroups(data.groups));
}, []); // empty array → run only once
Enter fullscreen mode Exit fullscreen mode
  • API is called once when component appears
  • groups state updates → React re-renders the UI automatically

5. Cleanup Function (Optional but Important)

Sometimes effects need cleanup, like:

  • Removing event listeners
  • Clearing timers
  • Canceling subscriptions
useEffect(() => {
  const timer = setInterval(() => console.log("Tick"), 1000);

  // cleanup function
  return () => clearInterval(timer);
}, []);
Enter fullscreen mode Exit fullscreen mode

Think of it as undoing something before the component disappears, similar to closing a DB connection.


6. Common Beginner Mistakes

Mistake Why It Happens How to Fix
Forgetting [] when effect should run once Effect runs on every render → infinite API calls Add empty dependency array []
Updating state without dependency Infinite loop: state changes → render → effect → state Include correct dependencies [state] or move code to a button click
Using useEffect for user actions e.g., clicking a button should not run automatically Keep useEffect for side effects, not triggers

7. Golden Rules

  1. useEffect = side effects, not user actions
  2. Empty array [] = run once
  3. Dependencies [value] = run when value changes
  4. Return a cleanup function if needed
  5. Don’t use useEffect to replace normal function calls triggered by buttons

8. Quick Mental Model (Backend-Friendly)

Backend Concept React useEffect Equivalent
API request on page load useEffect(() => fetchData(), [])
API request on parameter change useEffect(() => fetchData(), [param])
Closing DB connection return () => cleanup()

9. Summary

  • useEffect is React’s way of doing things after rendering
  • Use it for:

    • Fetching data
    • Logging
    • Timers or subscriptions
  • Don’t use it for:

    • Button clicks
    • User input triggers (use event handlers instead)

✅ Once you understand useEffect, React stops feeling magical — it becomes predictable, just like backend logic:

  1. Load component → run effect
  2. Dependencies change → re-run effect
  3. Cleanup when leaving → prevent leaks

Top comments (0)