Skip to content

React - Kesalahan Umum useEffect (dan Cara Memperbaikinya)

Posted on:January 11, 2026 at 07:20 PM

Halo. Kalau kamu sudah ngoding pakai React, pasti pernah pusing gara-gara useEffect. Hook satu ini memang powerful, tapi paling gampang bikin bug kayak infinite loop atau data yang nggak update.

Dulu waktu saya pertama belajar hooks, saya pikir useEffect itu sama kayak componentDidUpdate. Wah, ternyata salah besar. Rasanya kayak saya lagi berantem sama framework-nya, bukan makai framework-nya.

Kali ini, saya mau bahas beberapa kesalahan umum yang sering saya lakukan (dan sering saya lihat orang lain lakukan) serta cara benerinnya.

1. Lupa Dependency Array

Ini penyebab utama infinite loop. Kalau kamu lupa naruh dependency array, effect bakal jalan setiap kali ada render. Kalau di dalam effect itu kamu update state, bakal trigger re-render, yang bakal trigger effect lagi… muter-muter terus deh.

Ini contoh kalau salah:

// ❌ BAD: Jalan setiap render
useEffect(() => {
  setCount(count + 1);
});

Buat benerinnya, kamu harus kasih tau React kapan effect ini harus jalan. Kalau cuma mau jalan sekali pas mount, kasih array kosong [].

// ✅ GOOD: Jalan cuma pas mount
useEffect(() => {
  console.log("Component mounted");
}, []);

2. Bohong soal Dependencies

Kadang ESLint suka ngomel karena kamu pake variabel di dalam useEffect tapi nggak dimasukin ke dependency array. Terus solusinya kamu matiin warning-nya?

Jangan ya. Itu bakal bikin “stale closures,” di mana effect kamu bakal pake nilai lama dari variabel karena dia nggak jalan ulang buat ambil nilai baru.

// ❌ BAD: 'count' bakal selalu nilai awal di dalam interval
useEffect(() => {
  const id = setInterval(() => {
    console.log(count); // nilai basi (stale)!
  }, 1000);
  return () => clearInterval(id);
}, []); // Bohong kalau kita nggak butuh 'count'

Solusinya: jujur aja. Kalau dipake, masukin list.

// ✅ GOOD: Effect jalan ulang pas count berubah
useEffect(() => {
  const id = setInterval(() => {
    console.log(count);
  }, 1000);
  return () => clearInterval(id);
}, [count]);

Atau lebih bagus lagi, pake functional update kalau kamu lagi set state, jadi kamu nggak perlu masukin count sebagai dependency.

3. Lupa Bersih-bersih (Cleanup)

useEffect itu juga tempat kita ngurus side effects kayak subscriptions atau event listeners. Kalau nggak dibersihin, mereka bakal numpuk setiap kali komponen re-render atau unmount, bikin memory leaks.

// ❌ BAD: Nambah listener baru tiap render, nggak pernah dihapus
useEffect(() => {
  const handleResize = () => console.log(window.innerWidth);
  window.addEventListener('resize', handleResize);
});

Selalu return cleanup function.

// ✅ GOOD: bersihin listener sebelumnya sebelum nambah yang baru
useEffect(() => {
  const handleResize = () => console.log(window.innerWidth);
  window.addEventListener('resize', handleResize);

  // Cleanup function
  return () => {
    window.removeEventListener('resize', handleResize);
  };
}, []);

Kesimpulan

useEffect itu bukan sihir. Intinya cuma buat sinkronisasi komponen kamu sama sistem luar. Perhatikan dependency array, jangan lupa cleanup, dan hidupmu bakal lebih tenang.

Semoga ini bisa bantu kamu ngurangin waktu debugging. Happy coding!