React: Membangun Antarmuka Pengguna · 4/9
State dengan useState
Memori yang bertahan melewati re-render, dan aturan bahwa pembaruan state tidak langsung terjadi.
Baca 30 menit
Setelah pelajaran ini kamu bisa
- Menambahkan state ke sebuah component dengan `useState`
- Menjelaskan kenapa pembaruan state tidak langsung terjadi
- Memakai functional update, dan menyebutkan kapan itu wajib
- Menjelaskan kenapa state harus diganti, jangan dimutasi
State adalah memori yang bertahan melewati re-render dan, saat berubah, justru memicunya. Variable biasa di dalam component di-reset setiap render, itu sebabnya ia tidak bisa menyimpan apa pun.
import { useState } from "react";
function Counter() {
// [ the current value, a function to change it ]
const [count, setCount] = useState(0); // 0 is the initial value
return (
<button onClick={() => setCount(count + 1)}>
Clicked {count} times
</button>
);
}useState mengembalikan array berisi tepat dua hal, jadi ia selalu di-destructure. Konvensi penamaannya [thing, setThing].Pembaruan masuk queue, bukan langsung
Ini hal paling mengejutkan tentang useState, dan ia menyebabkan bug yang hampir ditulis semua orang sekali.
function Broken() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
setCount(count + 1);
setCount(count + 1);
console.log(count); // still the OLD value - 0 on the first click
}
// Result: count becomes 1, not 3.
}
function Fixed() {
const [count, setCount] = useState(0);
function handleClick() {
setCount((c) => c + 1); // "whatever it is, add one"
setCount((c) => c + 1);
setCount((c) => c + 1);
}
// Result: count becomes 3.
}Queue yang menjelaskannya. Ini benar-benar cara React memproses pembaruan yang kamu minta.
Hasil
Tekan Jalankan untuk melihat hasilnya.
Ini jalan di browser kamu, di dalam sandbox. Apa pun yang kamu tulis di sini tidak bisa merusak situs.
Alasannya kembali soal closure: count adalah const milik render *ini*. Ia tidak bisa berubah. setCount(count + 1) berarti "jadikan 1", diucapkan tiga kali. setCount(c => c + 1) berarti "tambah satu pada nilainya nanti", dan itu bisa disusun bertumpuk.
Ganti, jangan mutasi
React mendeteksi perubahan dengan membandingkan reference. Memutasi object atau array di tempat membuat reference-nya tetap sama, jadi React tidak melihat apa pun dan tidak re-render. Ini pelajaran reference dari modul 2, datang sebagai bug UI.
Pemeriksaan perubahan React yang sebenarnya, dalam satu baris. Jalankan dan lihat pembaruan mana yang ia sadari.
Hasil
Tekan Jalankan untuk melihat hasilnya.
Ini jalan di browser kamu, di dalam sandbox. Apa pun yang kamu tulis di sini tidak bisa merusak situs.
Memilih apa yang masuk ke state
- Jaga tetap minimal. Kalau sebuah nilai bisa dihitung dari state lain, hitung saja — pelajaran dua langkah lagi membahas ini.
- Kelompokkan yang berubah bersama. Field yang berkaitan dalam satu object lebih baik daripada lima pemanggilan
useStateterpisah. - Jangan menaruh props ke dalam state. Itu menangkap nilai prop-nya sekali lalu mengabaikan pembaruan berikutnya. Sumber UI usang yang sangat umum.
- Modelkan state sebagai union, bukan boolean.
status: "loading" | "error" | "success"tidak bisa mewakili loading-dan-error sekaligus; empat boolean bisa.
Tugas praktik
Di proyek ini, buka features/lesson/runner/code-runner.tsx. Daftar setiap state yang dipegangnya dan jelaskan kenapa masing-masingnya perlu jadi state alih-alih variable biasa. Lalu temukan runningRef dan baca komentar yang menjelaskan kenapa ia sebuah ref dan bukan state — kamu akan sepenuhnya memahaminya setelah pelajaran ref.
Hasil yang diharapkan
Empat nilai state, masing-masing menggerakkan sesuatu yang terlihat di layar.
Cek pemahaman
Pilih jawaban dulu