Pernah nggak kamu bikin komponen React yang tampil sempurna di layar, tapi entah kenapa data-nya nggak muncul, timer-nya nggak jalan, atau malah memori komputer jadi boros? Nah, kemungkinan besar kamu belum kenal baik dengan useEffect hook dan konsep React lifecycle. Di artikel ke-6 dari Seri Belajar React: React from Zero to Zorro ini, kita akan bedah tuntas topik yang sering bikin pemula garuk-garuk kepala — tapi sebenarnya sangat logis kalau dilihat dari analogi yang tepat. Siap? Gas! ๐
๐ฑ Apa Itu React Lifecycle? (Dan Kenapa Kamu Harus Peduli)
Bayangkan komponen React itu seperti tanaman. Setiap tanaman punya siklus hidup: ditanam (mounting), tumbuh dan berubah (updating), lalu suatu hari dipotong/dibuang (unmounting). Hal yang sama terjadi pada setiap komponen React yang kamu buat.
Nah, ada momen-momen tertentu dalam siklus hidup ini di mana kamu mau "nyisipin" aksi tertentu — misalnya ambil data dari API saat komponen baru muncul, atau bersihkan timer saat komponen dihapus. Di sinilah useEffect hook berperan sebagai "penjadwal aksi" di sepanjang React lifecycle.
callback = fungsi yang dijalankan | dependencies = array penentu kapan useEffect dijalankan ulang
Sebelum React Hooks hadir di versi 16.8 (2019), lifecycle hanya bisa dipakai di class component dengan method seperti componentDidMount, componentDidUpdate, dan componentWillUnmount. Sekarang? Cukup satu hook: useEffect. Bersih, simpel, powerful.
๐️ Memahami useEffect Hook: 3 Mode yang Wajib Kamu Kuasai
useEffect hook bukan satu-cara-untuk-semua. Ia punya 3 mode berbeda tergantung isi array dependencies-nya. Ini yang paling penting kamu pahami sebelum mulai coding.
| Mode | Sintaks | Kapan Jalan? | Contoh Kegunaan |
|---|---|---|---|
| Tanpa dependencies | useEffect(() => {}) |
Setiap render | Logging, analitik sederhana |
| Array kosong | useEffect(() => {}, []) |
Hanya sekali (mount) | Fetch data awal, setup event |
| Dengan dependencies | useEffect(() => {}, [x, y]) |
Saat x atau y berubah | Refetch berdasarkan filter, sync state |
Lupa nulis array dependencies [] itu dosa besar pemula React! Efeknya? useEffect kamu akan jalan terus setiap render — bayangkan fetch API yang dipanggil ratusan kali tanpa henti. Selalu tentukan kapan useEffect boleh jalan.
๐ป Praktikum Langsung: useEffect Hook dari Kasus Nyata
Teori tanpa praktik itu ibarat peta tanpa kaki — nggak kemana-mana. Yuk kita langsung coba 3 kasus penggunaan useEffect yang sering muncul di dunia nyata.
Kasus: Update Judul Tab Browser Otomatis
Kita buat counter sederhana. Setiap kali angkanya berubah, judul tab browser ikut berubah. Ini contoh sempurna "side effect" — sesuatu yang terjadi di luar render React.
import { useState, useEffect } from 'react'; function Counter() { const [count, setCount] = useState(0); // ๐ฏ useEffect jalan setiap kali "count" berubah useEffect(() => { document.title = `Counter: ${count}`; }, [count]); // ← dependency array return ( <div> <p>Angka sekarang: {count}</p> <button onClick={() => setCount(count + 1)}> Tambah </button> </div> ); } export default Counter;
Kasus: Fetch Data Saat Komponen Pertama Kali Muncul
Ini usecase paling umum: ambil data dari API saat komponen di-mount. Gunakan array kosong [] supaya hanya jalan sekali.
import { useState, useEffect } from 'react'; function UserList() { const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); // ๐ Array [] = jalankan HANYA sekali saat mount useEffect(() => { fetch('https://jsonplaceholder.typicode.com/users') .then(res => res.json()) .then(data => { setUsers(data); setLoading(false); }); }, []); // ← array kosong = hanya saat mounting if (loading) return <p>Loading...</p>; return ( <ul> {users.map(user => ( <li key={user.id}>{user.name}</li> ))} </ul> ); } export default UserList;
Kasus: Cleanup Function — Cegah Memory Leak!
Ini bagian yang sering dilupakan pemula. Saat kamu setup timer, subscription, atau event listener di useEffect, kamu wajib membersihkannya saat komponen unmount via cleanup function.
import { useState, useEffect } from 'react'; function Timer() { const [seconds, setSeconds] = useState(0); useEffect(() => { // Setup interval saat mount const interval = setInterval(() => { setSeconds(prev => prev + 1); }, 1000); // ๐งน Cleanup: hapus interval saat unmount return () => clearInterval(interval); }, []); return <p>Timer: {seconds} detik</p>; } export default Timer;
Memory leak terjadi ketika kamu lupa cleanup event listener atau interval. Gejalanya: aplikasi makin lambat seiring waktu. Selalu return cleanup function dari useEffect jika kamu setup sesuatu yang "terus berjalan".
๐ Analisis: Kesalahan Umum useEffect Hook yang Harus Dihindari
// Tanpa cleanup — memory leak! useEffect(() => { window.addEventListener( 'resize', handleResize ); }); // ← tanpa []
// Dengan cleanup yang tepat useEffect(() => { window.addEventListener( 'resize', handleResize ); return () => { window.removeEventListener( 'resize', handleResize ); }; }, []);
React 18 menjalankan useEffect dua kali di Strict Mode saat development — ini bukan bug, tapi fitur untuk membantu kamu menemukan efek yang tidak bersih (missing cleanup). Di production, efek hanya berjalan sekali seperti biasa. Jadi jangan panik kalau lihat dua fetch di console!
Kalau useEffect kamu mulai panjang dan kompleks, itu sinyal untuk dipecah ke custom hook sendiri. Contoh: useFetch(url) atau useWindowResize(). Kode jadi lebih bersih dan reusable. Custom hooks akan kita bahas lebih dalam di artikel mendatang!
Artikel ini adalah bagian ke-6 dari 16 artikel dalam seri belajar React paling lengkap. Mulai dari instalasi, JSX, props, state, hingga deployment — semua ada di sini. Buka daftar isi lengkapnya dan pilih artikel sesuai levelmu!
No comments:
Post a Comment