State: Memori dari Sebuah Komponen
Seringkali komponen perlu mengubah tampilan di layar sebagai respons terjadinya interaksi dari pengguna. Mengetik di dalam form akan memperbarui kolom masukan (input field), menekan tombol “Selanjutnya” pada slide gambar akan mengganti gambar yang ditampilkan, menekan “Beli” akan menambahkan barang ke dalam keranjang. Komponen perlu “mengingat” informasi-informasi ini: nilai kolom input, gambar, dan isi keranjang belanja. Dalam React, ingatan (memory) yang dimiliki komponen ini disebut state.
You will learn
- Bagaimana menambahkan state dengan Hook
useState
- Pasangan variabel yang dikembalikan oleh Hook
useState
- Bagaimana menambahkan lebih dari satu variabel state
- Mengapa lingkup state bersifat lokal ke komponen
Saat variabel biasa kurang memadai
Di bawah adalah komponen yang merender sebuah gambar pahatan. Menekan tombol “Selanjutnya” seharusnya menampilkan gambar pahatan yang berikutnya dengan mengganti nilai index
menjadi 1
, lalu 2
, dan seterusnya. Namun, komponen ini belum bekerja (Boleh Anda cek!):
event handler handleClick
memperbarui nilai variabel index
. Namun dua hal mencegah pembaruan tersebut ditampilkan ke pengguna:
- Variabel lokal tidak dipertahankan antarrender. Saat React merender komponen ini untuk kedua kalinya, dia membuatnya ulang dari awal—tidak memerhatikan adanya perubahan ke variabel tersebut.
- Perubahan terhadap variabel lokal tidak memicu render. React tidak menyadari kalau dia perlu melakukan renderulang dengan data yang baru.
Untuk memperbarui komponen dengan data baru, dua hal perlu terjadi:
- Mempertahankan data antarrender.
- Memicu React untuk merender ulang komponennya dengan data baru.
Dua hal tersebut bisa dicapai dengan Hook useState
:
- Sebuah variabel state untuk mempertahankan data antarrender.
- Sebuah fungsi state setter untuk memperbarui variabel dan memicu React untuk merender ulang komponen.
Menambahkan variabel state
Untuk menambahkan variabel state, impor useState
dari React di paling atas file:
import { useState } from 'react';
Lalu, ubah baris berikut:
let index = 0;
menjadi
const [index, setIndex] = useState(0);
index
merupakan variabel state dan setIndex
adalah fungsi setter.
Sintaks yang menggunakan
"["
dan"]"
digunakan untuk membongkar isi array dan memungkinkan Anda untuk membaca elemen dalam array tersebut. Array yang dikembalikan olehuseState
akan selalu berisi dua elemen.
Ini cara mereka bekerja dalam handleClick
:
function handleClick() { setIndex(index + 1); }
Sekarang, menekan tombol “Selanjutnya” akan mengganti gambar pahatan:
Menggunakan Hook pertama Anda
Dalam React, useState
, dan fungsi lainnya yang berawalan ”use
”, disebut sebuah Hook.
Hooks adalah fungsi spesial yang hanya tersedia hanya pada proses rendering (yang akan kita bahas lebih detail di halaman selanjutnya). Mereka memberikan Anda akses ke berbagai fitur React.
State adalah salah satu fitur tersebut, Anda akan menemui Hooks lainnya nanti.
Anatomi dari useState
Saat Anda memanggil useState
, Anda memberitahu React bahwa komponen ini harus mengingat sesuatu
const [index, setIndex] = useState(0);
Dalam kasus ini, Anda ingin React untuk mengingat index
.
Nilai yang dimasukan ke useState
adalah nilai awal dari variabel state. Dalam kasus ini, nilai awal index
disetel ke 0 dengan useState(0)
.
Tiap kali komponen Anda dirender, useState
kan mengembalikan array dengan dua elemen:
- Variabel state (
index
) dengan nilai yang Anda simpan. - Fungsi state setter (
setIndex
) yang akan memperbarui variabel state dan memicu React untuk melakukan render ulang.
Ini urutan yang terjadi:
const [index, setIndex] = useState(0);
- Komponen Anda render untuk pertama kali. Karena Anda memberikan
0
keuseState
sebagai nilai awal untukindex
, dia akan mengembalikan[0, setIndex]
. React akan menandai0
sebagai nilai state terbaru. - Anda memperbarui state Saat pengguna menekan tombol, dia akan memanggil
setIndex(index + 1)
di saatindex
bernilai0
, sehingga menjadisetIndex(1)
. Kali ini React akan mengingat nilai state terbaru adalah1
dan memicu render lain. - Render kedua React masih membaca
useState(0)
, namun karena sebelumnya dia ingat kalau Anda sudah mengatur nilaiindex
ke1
, ia mengembalikan[1, setIndex]
. - Dan pola ini berlanjut seterusnya!
Memberikan beberapa variabel state kepada komponen
Anda bisa memberikan sebanyak mungkin variabel state dengan berbagai macam tipe data ke sebuah komponen. Komponen di bawah memiliki dua variabel state, sebuah bilangan index
dan boolean showMore
yang berganti nilai saat Anda menekan “Tampilkan Detail”
Baiknya memang ada beberapa variabel state jika mereka tidak saling berhubungan, misal index
dan showMore
dalam contoh tadi. Tapi kalau Anda merasa dua state akan sering berganti nilai bersama, ada baiknya untuk menggabungkannya. Misal, jika Anda mempunyai form dengan beberapa kolom, akan lebih mudah jika ada satu variabel state berupa objek daripada ada variabel state untuk masing-masing kolom. Baca Memilih struktur state untuk tips lainnya.
Deep Dive
Anda mungkin memperhatikan kalau dalam pemanggilan useState
tidak ada informasi mengenai state mana yang terbaru. Tidak ada tanda pengenal yang dioper ke useState
, jadi bagaimana dia bisa tahu variabel state yang harus dikembalikan? Apakah ada cara ajaib seperti memproses fungsi Anda? Jawabannya adalah tidak.
Untuk dapat tetap memakai sintaks yang singkat, Hook bergantung pada pemanggilan yang konsisten di tiap render dalam komponen yang sama. Dalam prakteknya ini berjalan dengan baik karena jika Anda mengikuti ketentuan di atas (“panggil Hook hanya pada tingkat atas”), Hook akan selalu dipanggil dengan urutan yang sama. Sebagai tambahan, linter plugin akan memberitahu Anda kalau ada kesalahan yang luput.
Di balik layar, React menyimpan sebuah array berisi pasangan state untuk tiap komponen. Dia juga menandai pasangan state terbaru, yang mana diatur menjadi 0
sebelum render. Tiap kali pemanggilan useState
, React akan memberi pasangan state dan menambah nilai index. Anda bisa membaca lebih lanjut tentang mekanisme ini di React Hooks: Not Magic, Just Arrays.
Contoh di bawah tidak menggunakan React namun bisa memberi gambaran bagaimana useState
bekerja:
Anda tidak perlu mendalaminya untuk menggunakan React, tapi bisa memberi Anda gambaran kasar tentang cara kerjanya.
State terisolasi dan privat
Lingkup state terbatas pada komponen di mana dia dipanggil. Dalam kata lain, jika Anda merender komponen yang sama dua kali, tiap komponen akan memiliki state yang terpisah! Mengubah salah satunya tidak kan memengaruhi yang satunya.
Dalam contoh di bawah, komponen Gallery
dari sebelumnya dirender dua kali tanpa perubahan ke logikanya. Coba tekan tombol di dalam tiap galeri. Perhatikan bagaimana state mereka tidak saling memengaruhi
Inilah yang membedakan state dengan variabel biasa yang Anda deklarasikan di tingkat atas komponen. State tidak terikat ke pemanggilan fungsi tertentu atau lokasi di dalam kode, tapi dia “bersifat lokal” ke komponen spesifik di laman web. Anda merender dua buah komponen <Gallery />
makan state mereka disimpan secara terpisah.
Perhatikan juga bagaimana komponen Page
tidak “mengetahui” tentang state milik Gallery
atau bahkan ada-tidaknya. Tidak seperti props, state bersifat privat ke komponen tempat dia dideklarasikan. Komponen parent tidak dapat mengubahnya. Sehingga Anda bisa menambahkan atau menghapus state tanpa memengaruhi komponen lainnya.
Bagaimana jika Anda ingin menjaga state di kedua Gallery
tetap sinkron? Cara yang benar dalam React adalah menghapus state dari komponen anak (child) dan memindahkannya ke komponen Induk (parent) terdekat yang sama. Beberapa halaman berikutnya akan fokus ke mengatur state dalam sebuah komponen, tapi kita akan kembali ke topic ini di Sharing State Between Components.
Recap
- Gunakan variabel state saat komponen perlu mengingat informasi antarrender.
- Variabel state dideklarasikan dengan Hook
useState
. - Hooks adalah fungsi spesial yang diawali
use
. Mereka memberi Anda akses ke fitur-fitur React seperti state. - Hooks mungkin mengingatkan Anda ke pernyataan impor: mereka perlu dipanggil tanpa syarat. Memanggil Hooks, termasuk
useState
, hanya bisa pada tingkat atas sebuah komponen atau Hook lainnya. - Hook
useState
mengembalikan pasangan nilai: nilai state terbaru dan fungsi untuk memperbaruinya. - Anda bisa memliki lebih dari satu variabel state. Di balik layar, React akan menandainya sesuai urutan pemanggilannya.
- State bersifat privat ke komponennya. Jika Anda merendernya di dua tempat, tiap komponen memiliki state masing-masing.
Challenge 1 of 4: Lengkapi galerinya
Jika Anda menekan “Selanjunya” di gambar pahatan terakhir, kodenya akan berhenti bekerja. Coba perbaiki logikanya untuk mencegah hal tersebut. Anda bisa melakukannya dengan menambahkan pengecekan di event hanler atau menonaktifkan tombolnya saat tidak ada aksi yang mungkin terjadi.
Setelah memperbaiki kesalahannya, tambahkan tombol “Sebelumnya” untuk menampilkan gambar pahatan yang sebelumnya. Kodenya harus berjalan lancar sampai gambar yang pertama tampil.