Aplikasi React dibangun dari komponen, dan setiap komponen menjalani sebuah siklus hidup. Ia muncul di layar. Ia bereaksi terhadap informasi baru. Akhirnya, ia menghilang. Abaikan ritme tersebut, dan risikonya nyata. Kebocoran memori (memory leaks) mulai muncul. Performa render menurun. Pengguna mengklik tombol yang tidak lagi merespons karena komponen yang terhubung dengannya telah di-unmount sepuluh menit yang lalu, tetapi event listener-nya masih aktif. Memahami siklus hidup komponen bukanlah sekadar latihan akademis. Ini adalah fondasi dalam menulis perangkat lunak yang tetap andal dalam penggunaan nyata.

Bayangkan keberadaan sebuah komponen dalam tiga tahap. Pengembang sering menggambarkannya sebagai kelahiran, pertumbuhan, dan kematian. React menyebutnya mounting, updating, dan unmounting. Setiap tahap memiliki tugas khusus, dan masing-masing memberi Anda momen yang tepat untuk menjalankan kode atau membersihkannya.

Tiga Fase

Mounting adalah kelahiran. Komponen dibuat dan dimasukkan ke dalam DOM browser untuk pertama kalinya. Ini adalah jendela pengaturan (setup) Anda. Jika komponen membutuhkan data jarak jauh, inilah saat Anda memintanya. Jika ia membutuhkan state awal yang dihitung dari props, Anda melakukannya di sini. Di era komponen kelas (class component), ini adalah ranah componentDidMount. Dengan komponen fungsional modern, Anda menanganinya dengan useEffect dan dependency array yang kosong. Detail kuncinya adalah blok kode ini berjalan satu kali, segera setelah React menempatkan elemen ke dalam halaman. Hal ini membuatnya ideal untuk pengaturan satu kali seperti mengambil profil pengguna atau membaca nilai dari localStorage.

Updating adalah pertumbuhan. Komponen yang sudah ter-mount tidak diam saja. Props datang dari induk (parent). State berubah karena interaksi pengguna. Induk itu sendiri melakukan re-render, yang memaksa anak (child) untuk mengikutinya. React kemudian melakukan re-render pada komponen untuk menjaga UI tetap sinkron dengan data Anda. Fase ini berulang berkali-kali selama masa hidup komponen. Setiap kali dependensi berubah, effect Anda berjalan lagi, dan komponen memberikan output baru kembali ke DOM. Karena fase ini dipicu begitu sering, di sinilah sebagian besar masalah performa bermula. Pekerjaan yang tidak perlu di sini akan menumpuk dengan cepat.

Unmounting adalah kematian. Komponen meninggalkan layar, mungkin karena pengguna berpindah ke halaman lain atau conditional render dimatikan. Pada titik ini, komponen dihancurkan, tetapi dunia luar tidak selalu mengetahuinya. Timer terus berjalan. WebSocket terus mendengarkan. Event listener pada objek window tetap terpasang. Jika Anda tidak membersihkan hal-hal ini, mereka akan menahan referensi ke komponen yang sudah mati dan menyebabkan kebocoran memori (memory leak). Browser membuang-buang siklus pada "hantu". React memberi Anda fungsi pembersihan (cleanup function) agar Anda dapat menghentikan interval, menutup koneksi, dan menghapus listener sebelum komponen menghilang selamanya.

Dari Metode Kelas ke Hooks

Selama bertahun-tahun, para insinyur React mengelola fase-fase ini melalui komponen kelas. Logika terbagi di berbagai metode yang berbeda. Anda mengambil data di dalam componentDidMount, merespons perubahan prop di dalam componentDidUpdate, dan "menyapu lantai" di dalam componentWillUnmount. Masalahnya adalah logika yang terkait akhirnya menjadi tersebar. Satu fitur tunggal, seperti koneksi obrolan langsung (live chat), memerlukan kode di tiga metode siklus hidup yang terpisah hanya untuk menyambungkan, memeriksa perubahan utas (thread), dan memutuskan koneksi.

Hooks mengubah hal itu. Hook useEffect pada komponen fungsional memungkinkan Anda mengelompokkan logika berdasarkan tujuan, bukan berdasarkan fase siklus hidup. Meski begitu, model mentalnya tetap selaras jika Anda tahu ke mana harus mencari.

Untuk menangani mounting, tulis useEffect(() => { ... }, []). Dependency array yang kosong memberi tahu React bahwa effect ini tidak memiliki dependensi eksternal, sehingga hanya berjalan setelah render awal. Ini menggantikan componentDidMount.

Untuk menangani pembaruan (updates), sertakan nilai spesifik yang harus dipantau oleh React: useEffect(() => { ... }, [dependency]). Ketika dependency berubah di antara render,