DEV Community

Selahaddin Osmanoglu
Selahaddin Osmanoglu

Posted on

Part 6: useEffect and Side Effects – React Beyond Rendering

Welcome to Part 6 of the React for Beginners series!

Up to this point, your components have been all about rendering and local interactions. But what if your component needs to:

  • Fetch data from an API?
  • Set up a timer or subscription?
  • Manipulate the DOM manually?

That’s where side effects and the useEffect hook come in.


💡 What Is a Side Effect?

A side effect is anything your component does outside the scope of rendering.

Examples:

  • Data fetching
  • Logging
  • Subscribing to events
  • Directly changing the DOM
  • Setting timeouts/intervals

React provides the useEffect hook for handling these safely.


🔧 Basic useEffect Syntax

import { useEffect } from 'react';

useEffect(() => {
  // Do something (the side effect)
}, []);
Enter fullscreen mode Exit fullscreen mode
  • The function runs after the component renders.
  • The empty array ([]) means it only runs once (on mount).

🧪 Example: Log When Component Loads

import { useEffect } from 'react';

function Logger() {
  useEffect(() => {
    console.log('Component mounted!');
  }, []);

  return <p>Check the console!</p>;
}
Enter fullscreen mode Exit fullscreen mode

📝 The message only logs once when the component first appears.


📡 Example: Fetch Data from an API

import { useEffect, useState } from 'react';

function PostList() {
  const [posts, setPosts] = useState([]);

  useEffect(() => {
    fetch('https://jsonplaceholder.typicode.com/posts?_limit=5')
      .then((res) => res.json())
      .then((data) => setPosts(data));
  }, []);

  return (
    <div>
      <h2>Latest Posts</h2>
      <ul>
        {posts.map((p) => (
          <li key={p.id}>{p.title}</li>
        ))}
      </ul>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

✅ This fetches and displays 5 posts only once when the component mounts.


🔁 Re-running useEffect

Add values to the array to re-run the effect when they change:

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

This runs the effect every time count changes.


❌ Cleanup with return()

Some side effects need cleanup, like intervals or event listeners:

useEffect(() => {
  const id = setInterval(() => {
    console.log('Tick');
  }, 1000);

  return () => clearInterval(id); // Clean up on unmount
}, []);
Enter fullscreen mode Exit fullscreen mode

✅ This avoids memory leaks or unwanted behavior.


⚠️ Common Mistakes to Avoid

  • Don’t use async directly in useEffect — use an inner async function.
  • Avoid unnecessary re-renders by controlling your dependencies in the array.
  • Always clean up effects that leave things running (e.g., intervals, subscriptions).

✍️ Challenge for You

Create a RandomUser component:

  • On load, fetch a random user from https://randomuser.me/api/
  • Display their name and picture.
  • Show a loading message while fetching.

✅ Summary

  • useEffect lets you perform side effects after a render.
  • It replaces lifecycle methods like componentDidMount in class components.
  • Use dependency arrays to control when it runs.
  • Clean up effects when necessary using return() inside useEffect.

🔜 What’s Next?

In Part 7, we’ll learn how to handle user input and forms using controlled components.

You're now ready to work with real-world APIs and asynchronous code! 🚀

Top comments (0)