useEffect Dasar — React

Komponen React punya tugas utama: render UI dari state. Tapi banyak hal yang perlu jalan DI LUAR render — fetch data dari API, set timer, listen ke window resiz

Komponen React punya tugas utama: render UI dari state. Tapi banyak hal yang perlu jalan DI LUAR render — fetch data dari API, set timer, listen ke window resize, update document.title, manipulasi localStorage. Operasi ini punya nama: side effects. useEffect adalah hook yang ngasih kamu cara JALANIN side effect SECARA AMAN — di waktu yang tepat, dengan cleanup yang proper, tanpa ngeganggu render cycle React.

🤔 Kenapa gak langsung di body komponen? function App() { fetch("/api/data"); ... } jalan tiap render = 1000 fetch dalam 10 detik = server kena flood. useEffect ngasih kontrol KAPAN side effect dipanggil (mount, dependency change, atau unmount), bukan tiap render. Plus React tau cara cleanup-nya pas component unmount — gak ada memory leak.

import { useEffect } from "react"

function App() {
  useEffect(() => {
    console.log("Komponen dimuat!")
    document.title = "Halaman Baru"
  }, [])  // [] = hanya sekali saat mount

  return <p>Cek console dan judul tab!</p>
}

Dependency Array — Kapan Effect Jalan

Pattern Kapan dijalankan
useEffect(() => {...}, []) Sekali saat mount (paling umum)
useEffect(() => {...}, [count]) Saat count berubah
useEffect(() => {...}, [a, b]) Saat a ATAU b berubah
useEffect(() => {...}) Setiap render (jarang dipake — biasanya bug)

Contoh: Sync state ke DOM

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

  useEffect(() => {
    document.title = `Hitungan: ${count}`
  }, [count])  // re-run tiap count berubah

  return <button onClick={() => setCount(c => c + 1)}>+1</button>
}

Contoh: Fetch Data

function UserList() {
  const [users, setUsers] = useState([])
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    fetch("/api/users")
      .then(r => r.json())
      .then(data => {
        setUsers(data)
        setLoading(false)
      })
  }, [])  // sekali saat mount

  if (loading) return <p>Loading...</p>
  return <ul>{users.map(u => <li key={u.id}>{u.name}</li>)}</ul>
}

🎭 Analogi sehari-hari

useEffect itu kayak alarm di HP kamu. Alarm harian (useEffect(..., [])) = setel sekali, bunyi tiap pagi (setelah mount). Alarm reminder ulang tahun teman (useEffect(..., [tanggal])) = bunyi cuma pas tanggal tertentu cocok. Alarm gak boleh dipanggil di tengah aktivitas masak (render) — bisa rusak proses. HP nge-handle scheduling otomatis: "kapan bunyi, kapan stop, kapan reset". useEffect sama: kasih instruksi (effect function), kasih kondisi kapan jalan (deps array), React urus timing-nya. Plus pas HP mati (component unmount), alarm otomatis di-clear — itu cleanup function (lesson selanjutnya).

⚠️ Jebakan yang sering ditemui

🎯 Butuh useEffect? Atau bisa pakai cara lain?

  • Sync ke browser API (document.title, localStorage, scroll position) → useEffect
  • Subscribe ke event (window resize, websocket, timer) → useEffect ✓ + cleanup
  • Fetch datauseEffect ✓ (lebih baik: TanStack Query / SWR / RSC)
  • Hitung nilai dari props/state → JANGAN useEffect, hitung langsung di body component
  • Sync state turunan (e.g., fullName = first + last) → JANGAN useEffect, derive langsung
  • Reset state pas prop berubah → bisa key prop di parent (lebih clean), atau useEffect dengan deps prop
  • Run sekali saat klik tombol → JANGAN useEffect, panggil di event handler langsung

Aturan: pertanyaan pertama "ini bener-bener side effect?" — kalau jawabannya bisa dihitung dari state/props, jangan pakai useEffect. React 19 mulai banyak push pattern "less useEffect".

TL;DR: useEffect(fn, deps) = jalanin side effect (fetch, DOM, timer, subscription) di luar render cycle. [] = sekali saat mount. [x, y] = saat x atau y berubah. Tanpa deps = tiap render (jarang). Effect TIDAK boleh async langsung — bungkus inner function. Object/array di deps bikin re-run terus (pakai primitive). Hitung nilai dari state/props? JANGAN useEffect, derive langsung. Modern alternatif fetch: TanStack Query/SWR.

Yang akan kamu pelajari