💡 Key Takeaways

⚛️ useEffect: Manage side effects like data fetching, DOM updates, timers, and subscriptions.
🔹 Dependencies: Controls when the effect runs ([] for mount-only, list for selective updates).
⚙️ Cleanup: Return a function to remove listeners or timers, avoiding memory leaks.
📡 Async & Fetching: Wrap async logic inside effects; handle errors properly.
🔹 Patterns: Conditional effects and multiple dependencies for dynamic behavior.

⚛️ What is useEffect

  • Handles side effects in functional components
  • Replaces lifecycle methods (componentDidMount, componentWillUnmount)
  • Supports dependency arrays for selective updates
  • Allows cleanup to prevent memory leaks
import { useEffect } from 'react';

🔹 Basic Usage

  • Runs after every render by default
  • No dependencies triggers on all updates
  • Avoid blocking operations inside the effect
useEffect(() => {
  console.log("Effect runs after every render");
});

✅ Run Once on Mount

  • Pass empty array [] for mount-only behavior
  • Useful for initial data fetches or setup tasks
  • Equivalent to componentDidMount
useEffect(() => {
  console.log("Component mounted");
}, []);

🔄 Run on Dependency Change

  • Trigger effect on mount and when listed dependencies change
  • Keeps state and effects in sync
  • List only necessary dependencies to avoid extra renders
useEffect(() => {
  console.log(`Count is now ${count}`);
}, [count]);

⚙️ Cleanup Function

  • Return a function for cleanup
  • Runs before unmount or next effect
  • Ideal for timers, subscriptions, and event listeners
useEffect(() => {
  const timer = setInterval(() => console.log("tick"), 1000);

  return () => {
    clearInterval(timer);
    console.log("Cleaned up");
  };
}, []);

📡 Fetching Data

  • Wrap async calls inside the effect
  • Run once on mount or when dependencies change
  • Update state with fetched data
  • Handle errors to prevent unhandled rejections
useEffect(() => {
  async function fetchData() {
    const res = await fetch("/api/data");
    const json = await res.json();
    setData(json);
  }

  fetchData();
}, []);

🔹 Common Patterns

Conditional Effect

  • Run only if conditions are met
  • Avoid unnecessary operations
  • Useful for authenticated users or optional props
useEffect(() => {
  if (!user) return;
  console.log("User exists:", user);
}, [user]);

Watching Multiple Dependencies

  • Trigger when any dependency changes
  • Keep dependencies minimal to prevent extra renders
  • Useful for combined state updates or form validation
useEffect(() => {
  console.log("Either a or b changed:", a, b);
}, [a, b]);

Disclaimer: The information provided on this website is for educational and informational purposes only. Health-related content is not intended to serve as medical advice, diagnosis, or treatment recommendations and should not replace consultation with qualified healthcare professionals. Financial content is for educational purposes only and does not constitute financial advice, investment recommendations, or professional financial planning services. Always consult with licensed healthcare providers for medical concerns and qualified financial advisors for personalized financial guidance.