D DevBrainBox

React useEffect Hook

useEffect Hook

What is useEffect ?

useEffect is a React Hook that lets you run code after the component renders.

Ex: Whenever something changes (like state or props), I want to do something (like fetch data, update title, etc.)

useEffect(() => {
  // Your code here (side effect)
}, [dependencies]);
  • The function runs after the component renders.
  • The array [dependencies] controls when the effect should run.

Run on Every Render

import React, { useEffect, useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log('Component rendered or updated');
  });

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increase</button>
    </div>
  );
}

Run Only Once (on Mount)

useEffect(() => {
  console.log('Component mounted');
}, []);
  • Pass an empty array [] to run the effect only once, like componentDidMount.

Fetch API Data on Mount

import React, { useEffect, useState } from 'react';

function UserList() {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    fetch('https://jsonplaceholder.typicode.com/users')
      .then(res => res.json())
      .then(data => setUsers(data));
  }, []); // empty array = only once

  return (
    <ul>
      {users.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}

Run on Specific State Change

useEffect(() => {
  console.log('Count changed to', count);
}, [count]);
  • Only runs when count changes.

Clean Up Example (like componentWillUnmount)

useEffect(() => {
  const interval = setInterval(() => {
    console.log('Interval running');
  }, 1000);

  return () => {
    clearInterval(interval);
    console.log('Cleaned up');
  };
}, []);
  • return function is the cleanup, useful for timers, listeners, etc.
Type of DependencyWhen it Runs
[] (empty array)Once, on mount
[value]When value changes
(No array)On every render

Project: Live Crypto Price Tracker

This project will:

  • Use useEffect to fetch live cryptocurrency prices
  • Show them in a clean UI
  • Refresh automatically every 30 seconds

Tech Stack:

  • React (JS)
  • useEffect and useState hooks
  • Fetch API

CryptoTracker.jsx

import React, { useEffect, useState } from 'react';

export default function CryptoTracker() {
  const [crypto, setCrypto] = useState([]);
  const [loading, setLoading] = useState(true);

  // Fetch data using useEffect
  useEffect(() => {
    const fetchCrypto = async () => {
      setLoading(true);
      try {
        const response = await fetch(
          'https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&order=market_cap_desc&per_page=5&page=1'
        );
        const data = await response.json();
        setCrypto(data);
      } catch (error) {
        console.error('Error fetching data:', error);
      }
      setLoading(false);
    };

    fetchCrypto();

    const interval = setInterval(() => {
      fetchCrypto();
    }, 30000); // refresh every 30s

    return () => clearInterval(interval); // cleanup
  }, []);

  return (
    <div style={styles.container}>
      <h1>🚀 Live Crypto Price Tracker</h1>
      {loading ? (
        <p>Loading data...</p>
      ) : (
        <table style={styles.table}>
          <thead>
            <tr>
              <th>Coin</th>
              <th>Price (USD)</th>
              <th>24h Change</th>
            </tr>
          </thead>
          <tbody>
            {crypto.map((coin) => (
              <tr key={coin.id}>
                <td>
                  <img src={coin.image} alt={coin.name} style={styles.img} />
                  {coin.name}
                </td>
                <td>${coin.current_price.toLocaleString()}</td>
                <td style={{ color: coin.price_change_percentage_24h >= 0 ? 'green' : 'red' }}>
                  {coin.price_change_percentage_24h.toFixed(2)}%
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      )}
    </div>
  );
}

// Inline styles
const styles = {
  container: {
    padding: '2rem',
    fontFamily: 'Arial, sans-serif',
    background: '#f4f4f4',
    borderRadius: '12px',
    maxWidth: '700px',
    margin: 'auto',
    boxShadow: '0 0 15px rgba(0,0,0,0.1)'
  },
  table: {
    width: '100%',
    borderCollapse: 'collapse'
  },
  img: {
    width: '20px',
    verticalAlign: 'middle',
    marginRight: '8px'
  }
};
  • useEffect to fetch data on mount
  • Automatic refresh with setInterval
  • Cleanup with return function in useEffect
  • Conditional rendering (loading vs data)

On this page