ReactJS #10: useEffect – Melakukan Sesuatu Begitu Komponen Dimuat


ReactJS #10: useEffect

Melakukan Sesuatu Begitu Komponen Dimuat
(Seperti Menjemput Teman setelah Sekolah)

Halo, petualang React! 🌟

Pernahkah kamu pulang sekolah dan dijemput orang tua? Kamu menunggu di depan gerbang, lalu begitu melihat mobil jemputan, kamu langsung masuk dan pulang. Di React, kita juga sering perlu melakukan sesuatu setelah komponen "muncul" di layar, misalnya mengambil data dari internet, mengubah judul halaman, atau memulai timer. Untuk itu, kita punya alat bernama useEffect.

🏫➡️🚗➡️🏠
useEffect = "menjemput" setelah komponen selesai render

🔎 Apa Itu useEffect?

useEffect adalah Hook yang memungkinkan kita menjalankan efek samping (side effects) pada komponen. Efek samping adalah hal-hal yang tidak berhubungan langsung dengan tampilan, seperti:

  • Mengambil data dari API (web service).
  • Mengubah judul halaman (title).
  • Menyetel timer atau interval.
  • Menyimpan data ke penyimpanan lokal.

useEffect dijalankan setelah komponen selesai di-render ke layar. Jadi, seperti "penjemput" yang datang setelah sekolah usai.

📜 Sintaks useEffect

Berikut cara menulis useEffect:

import { useEffect } from 'react'; function Komponen() { useEffect(() => { // Kode efek ditulis di sini console.log('Efek dijalankan!'); // Opsional: fungsi pembersih (cleanup) return () => { console.log('Membersihkan efek...'); }; }, [/* dependencies (ketergantungan) */]); }

Penjelasan:

  • Parameter pertama: fungsi yang berisi efek kita.
  • Parameter kedua: array dependencies. Efek akan dijalankan ulang jika salah satu nilai di dalam array berubah.
  • Fungsi pembersih (opsional): jika efek memerlukan pembersihan (misalnya membersihkan timer), kita bisa mengembalikan fungsi dari dalam useEffect.

🧪 Contoh 1: Menjalankan Efek Sekali Saat Komponen Dimuat

Kita ingin mengambil data dari API palsu (JSONPlaceholder) begitu komponen muncul. Untuk menjalankan efek hanya sekali, kita beri array dependencies kosong [].

import { useState, useEffect } from 'react'; function DaftarPostingan() { const [posts, setPosts] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { // Ambil data dari API fetch('https://jsonplaceholder.typicode.com/posts?_limit=5') .then(response => response.json()) .then(data => { setPosts(data); setLoading(false); }) .catch(error => console.log(error)); }, []); // Array kosong = jalankan sekali saat mount if (loading) { return <p>⏳ Memuat data...</p> } return ( <div> <h3>📰 Daftar Postingan</h3> <ul> {posts.map(post => ( <li key={post.id}> <strong>{post.title}</strong> </li> ))} </ul> </div> ); }

Penjelasan:

  • Kita punya state posts untuk menyimpan data, dan loading untuk menampilkan teks "Memuat...".
  • Di dalam useEffect, kita melakukan fetch ke API. Setelah data datang, kita update state.
  • Array kosong [] memastikan efek hanya berjalan sekali saat komponen pertama kali dimuat.
💡 Catatan: JSONPlaceholder adalah API gratis untuk latihan. Coba ganti URL dengan API lain yang kamu suka.

🔄 Contoh 2: Efek yang Berjalan Ulang Saat State Berubah

Kadang kita ingin efek dijalankan ulang setiap kali nilai tertentu berubah. Misalnya, kita ingin mengubah judul halaman sesuai dengan jumlah klik pada counter.

import { useState, useEffect } from 'react'; function CounterWithTitle() { const [count, setCount] = useState(0); useEffect(() => { // Mengubah judul halaman document.title = `Kamu mengklik ${count} kali`; }, [count]); // Efek dijalankan ulang setiap count berubah return ( <div> <h2>Counter: {count}</h2> <button onClick={() => setCount(count + 1)}>➕ Klik</button> </div> ); }

Sekarang, setiap kali tombol diklik dan count berubah, judul tab browser akan ikut berubah. Coba lihat di tab browser, judulnya akan berganti!

🧹 Contoh 3: Membersihkan Efek (Cleanup)

Beberapa efek perlu dibersihkan agar tidak membocorkan memori. Contoh: timer (setInterval) atau langganan (subscription). Kita bisa mengembalikan fungsi dari useEffect untuk membersihkan.

import { useState, useEffect } from 'react'; function Timer() { const [detik, setDetik] = useState(0); useEffect(() => { const interval = setInterval(() => { setDetik(d => d + 1); // pakai fungsi updater agar aman }, 1000); // Fungsi pembersih: akan dipanggil saat komponen di-unmount return () => clearInterval(interval); }, []); // kosong, jalankan sekali return <h3>⏱️ Timer: {detik} detik</h3> }

Penjelasan:

  • Kita membuat interval yang menambah detik setiap 1000ms.
  • Fungsi yang dikembalikan akan dijalankan saat komponen dihapus dari layar (misal pindah halaman), membersihkan interval agar tidak terus berjalan di latar belakang.
  • Dengan array kosong, efek hanya berjalan sekali, tapi cleanup tetap dipanggil saat komponen tidak lagi digunakan.

⚠️ Hati-hati dengan Infinite Loop!

Jika kita lupa memberi array dependencies, atau memberi dependencies yang selalu berubah, efek bisa dijalankan terus-menerus. Contoh salah:

// ❌ SALAH: menyebabkan infinite loop useEffect(() => { setCount(count + 1); // mengubah state, menyebabkan re-render, useEffect dipanggil lagi, setCount lagi, dst... }); // tanpa array dependencies

Jika tidak ada array, useEffect dijalankan setiap render. Di dalamnya kita mengubah state, yang memicu render ulang, dan seterusnya. Ini akan membuat browser hang. Selalu perhatikan dependencies.

🧪 Latihan: Aplikasi Kutipan Acak

Buat komponen KutipanAcak yang:

  1. Saat pertama dimuat, menampilkan kutipan acak dari API https://api.quotable.io/random.
  2. Ada tombol "Kutipan Lainnya" yang ketika diklik akan mengambil kutipan baru dari API yang sama (tanpa reload halaman).
  3. Tampilkan status loading saat mengambil data.

Kerangka kode (coba isi sendiri):

import { useState, useEffect } from 'react'; function KutipanAcak() { const [kutipan, setKutipan] = useState(null); const [loading, setLoading] = useState(false); function ambilKutipan() { setLoading(true); fetch('https://api.quotable.io/random') .then(res => res.json()) .then(data => { setKutipan(data); setLoading(false); }); } // Pakai useEffect untuk mengambil kutipan pertama kali useEffect(() => { ambilKutipan(); }, []); // kosong, sekali saja return ( <div className="card"> <h3>💬 Kutipan Hari Ini</h3> {loading && <p>⏳ Mengambil kutipan...</p>} {kutipan && ( <> <p>"{kutipan.content}"</p> <p><em>— {kutipan.author}</em></p> </> )} <button onClick={ambilKutipan} disabled={loading}>🔄 Kutipan Lainnya</button> </div> ); }

Penjelasan: useEffect memanggil ambilKutipan saat komponen dimuat. Tombol juga memanggil fungsi yang sama untuk mengambil kutipan baru. Jangan lupa set loading agar tombol tidak diklik ganda.

🚀 Kesimpulan

  • useEffect digunakan untuk menjalankan efek samping setelah komponen dirender.
  • Array dependencies mengontrol kapan efek dijalankan ulang.
  • Kosong [] = sekali saat mount.
  • Berisi state/props = dijalankan ulang jika nilai berubah.
  • Tanpa array = dijalankan setiap render (hati-hati infinite loop).
  • Kembalikan fungsi dari useEffect untuk membersihkan efek (seperti menghapus timer).

Di artikel selanjutnya kita akan langsung mengambil data dari API (web service) dan menampilkannya dengan gaya yang lebih keren. Sampai jumpa!

Lebih baru Lebih lama

نموذج الاتصال