Pendahuluan
Bagi pengembang yang baru memasuki ekosistem React, memahami konsep State adalah salah satu langkah paling krusial. Bersama dengan Props, State adalah pilar utama yang mengendalikan bagaimana sebuah komponen React bekerja, menyimpan data, dan merespons interaksi pengguna.
Secara sederhana, State adalah memori internal dari sebuah komponen. Jika Props adalah data yang dikirimkan dari parent ke child (bersifat read-only), maka State adalah data lokal yang dikelola dan dapat diubah secara dinamis oleh komponen itu sendiri selama aplikasi berjalan.
Mengapa Variabel Biasa Tidak Cukup?
Mungkin Anda bertanya: “Mengapa kita tidak memakai variabel JavaScript biasa (seperti let atau var) untuk menyimpan data komponen?”
Mari perhatikan contoh berikut:
function Counter() {
let count = 0;
function handleClick() {
count = count + 1;
console.log("Nilai count:", count); // Nilai bertambah di console
}
return (
<div>
<p>Jumlah klik: {count}</p>
<button onClick={handleClick}>Klik Saya</button>
</div>
);
}
Jika Anda menjalankan kode di atas, setiap kali tombol diklik, fungsi handleClick akan berjalan dan nilai variabel count di memori memang akan bertambah (bisa dilihat di console.log). Namun, tampilan di layar browser (DOM) tetap menunjukkan angka 0.
Hal ini terjadi karena React tidak memantau perubahan variabel JavaScript biasa. Agar tampilan layar berubah, React perlu merender ulang (re-render) komponen tersebut. Di sinilah React State berperan. Ketika state berubah, React secara otomatis mendeteksi perubahan tersebut dan memperbarui DOM untuk mencocokkan keadaan terbaru.
Menggunakan Hook useState
Pada komponen fungsional (Functional Component), kita menggunakan fitur bawaan bernama Hook useState untuk membuat dan mengelola state.
Berikut adalah struktur dasar penulisan useState:
import { useState } from 'react';
const [stateName, setStateFunction] = useState(initialValue);
Mari kita bedah sintaksis di atas:
useState: Fungsi hook dari React yang menerima satu argumen berupa nilai awal (initial value) dari state tersebut. Nilai awal ini bisa berupa angka, string, boolean, objek, maupun array.stateName: Variabel yang menampung nilai state saat ini.setStateFunction: Fungsi khusus yang digunakan untuk memperbarui nilai state. Kita tidak boleh mengubahstateNamesecara langsung; kita harus selalu menggunakan fungsi ini agar React tahu bahwa state telah berubah dan perlu memicu re-render.- Destructuring Array: Sintaks
[stateName, setStateFunction]memanfaatkan fitur array destructuring pada ES6 JavaScript untuk mengekstrak dua elemen yang dikembalikan oleh fungsiuseState.
Contoh Implementasi: Komponen Counter yang Berfungsi
Sekarang, mari kita ubah contoh variabel biasa sebelumnya menjadi komponen yang menggunakan React State:
import { useState } from 'react';
function Counter() {
// Membuat state dengan nama 'count' dan nilai awal 0
const [count, setCount] = useState(0);
function handleClick() {
// Memperbarui state menggunakan fungsi setter-nya
setCount(count + 1);
}
return (
<div class="p-6 border border-gray-200 rounded-xl max-w-xs text-center">
<p class="text-xl mb-4 font-semibold">Jumlah klik: {count}</p>
<button
onClick={handleClick}
class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-lg transition-colors"
>
Klik Saya
</button>
</div>
);
}
Ketika tombol di atas diklik:
- Fungsi
handleClickmemanggilsetCount(count + 1). - React memperbarui nilai memori
countmenjadi1. - React menjadwalkan render ulang untuk komponen
Counter. - Komponen
Counterdieksekusi kembali, kali ini nilaicountadalah1, dan DOM diperbarui secara instan.
Prinsip Penting dalam Mengelola State
Agar terhindar dari bug yang membingungkan saat mengembangkan aplikasi React berskala besar, pahami prinsip-prinsip penting berikut:
1. Jangan Pernah Mengubah State Secara Langsung (Immutability)
React mengandalkan perbandingan alamat memori (reference comparison) untuk mendeteksi perubahan data. Jika Anda mengubah isi array atau objek secara langsung tanpa memanggil fungsi setter, React tidak akan tahu bahwa data tersebut berubah.
-
Salah:
const [user, setUser] = useState({ name: 'Aji', age: 25 }); user.age = 26; // React tidak akan merender ulang! -
Benar (Gunakan operator spread
...untuk menyalin data lama):const [user, setUser] = useState({ name: 'Aji', age: 25 }); setUser({ ...user, age: 26 // Mengganti properti age secara aman });
2. State Updates Bersifat Asynchronous
Perlu diingat bahwa pemanggilan fungsi updater seperti setCount tidak langsung mengubah nilai variabel di baris kode berikutnya. React mengelompokkan beberapa pembaruan state (batching) demi optimasi performa.
const [count, setCount] = useState(0);
const handleClick = () => {
setCount(count + 1);
console.log(count); // Masih akan mencetak 0, bukan 1!
};
Jika pembaruan state Anda berikutnya sangat bergantung pada nilai state saat ini (seperti antrean tindakan), disarankan untuk menggunakan callback function:
setCount(prevCount => prevCount + 1);
3. Letakkan State di Tempat yang Tepat (Lifting State Up)
Jika dua atau lebih komponen perlu berbagi atau menggunakan state yang sama, letakkan state tersebut pada komponen induk terdekat yang menaungi komponen-komponen tersebut (common parent), lalu distribusikan melalui Props. Hal ini membantu menjaga aliran data tetap satu arah (one-way data flow) yang konsisten.
Kesimpulan
React State memberikan kemampuan luar biasa untuk membuat antarmuka pengguna yang dinamis, interaktif, dan reaktif. Dengan menguasai konsep dasar useState, prinsip immutability, dan cara kerja re-render, Anda sudah memiliki modal yang kuat untuk membangun aplikasi web modern menggunakan React.