State: Component Yang Mengingat
18 minitPertengahanReact
Dalam pelajaran ini
- ▸Terangkan kenapa variable biasa tidak boleh mengemas kini skrin
- ▸Cipta state dengan
useStatedan kemas kini dengan setter-nya - ▸Kemas kini array dan objek dengan mencipta yang baharu, bukan memutasi
- ▸Guna kemas kini berfungsi bila nilai seterusnya bergantung pada nilai sebelumnya
Idea utama
State ialah data yang diingati oleh component antara render. Bila anda panggil setter, React menjalankan component anda semula dengan nilai baharu dan mengemas kini skrin.
Props datang dari induk. Tetapi sesetengah data milik component itu sendiri dan berubah semasa pengguna berinteraksi: kaunter, senarai pesanan, sama ada menu dibuka. Itulah state.
Kenapa variable biasa tak berfungsi
Component ialah function. Setiap kali React me-render-nya, function itu berjalan dari atas — jadi let cups = 0 bermula pada 0 setiap kali render. Dan menukar variable tempatan tidak memberitahu React apa-apa, jadi ia tidak re-render. Variable itu berubah; skrin tidak.
Lupa, dan React tidak diberitahu
function Counter() {
let cups = 0;
function add() {
cups = cups + 1; // changes, but no re-render
}
return <button onClick={add}>{cups}</button>;
}Diingati, dan mencetuskan re-render
import { useState } from "react";
function Counter() {
const [cups, setCups] = useState(0);
function add() {
setCups(cups + 1); // new value + re-render
}
return <button onClick={add}>{cups}</button>;
}- useState(initial)
- Sebuah hook — function khas React yang namanya bermula dengan
use. Ia memulangkan sepasang: nilai semasa dan function untuk mengubahnya. - const [cups, setCups]
- Destructuring array. Namakan apa sahaja yang anda suka; kebiasaannya
thingdansetThing. - Re-render
- React memanggil function component anda sekali lagi. Kali ini
useStatememulangkan nilai baharu, dan React mengemas kini hanya bahagian DOM yang berubah.
Peraturan hook
Panggil useState di peringkat atas component anda — bukan di dalam if, gelung atau function bersarang. React membezakan hook mengikut susunan ia dipanggil, jadi susunan itu mesti sama setiap kali render.
Peraturan 1: jangan mutasi state
React menentukan sama ada perlu re-render dengan menyemak sama ada nilai baharu itu nilai yang berbeza (ia guna Object.is). Kalau anda push ke dalam array yang sama dan hantar semula array yang sama itu, React nampak "tiada apa berubah" dan langkau kemas kini. Sentiasa cipta array atau objek yang baharu.
Mutasi (tiada re-render)
orders.push("Order #3");
setOrders(orders); // same array!
user.name = "Siti";
setUser(user); // same object!Nilai baharu (re-render)
setOrders([...orders, "Order #3"]);
setUser({ ...user, name: "Siti" });
setOrders(orders.filter((o) => o !== "Order #1"));Peraturan 2: bergantung pada nilai sebelum? Hantar function
Dalam satu render, cups ialah snapshot — nombor yang tetap. Memanggil setter tidak mengubahnya; ia meminta React membuat render baharu. Jadi kalau anda beratur beberapa kemas kini daripada snapshot yang sama, semuanya mengira daripada nombor lama yang sama. Hantar function updater sebaliknya dan React akan memberinya nilai terkini.
Tambah 1, bukan 3 (cups tetap 0)
function addThree() {
setCups(cups + 1); // 0 + 1
setCups(cups + 1); // 0 + 1
setCups(cups + 1); // 0 + 1
}Tambah 3
function addThree() {
setCups((c) => c + 1); // 0 → 1
setCups((c) => c + 1); // 1 → 2
setCups((c) => c + 1); // 2 → 3
}Masalah snapshot yang sama muncul dengan pemasa: callback setTimeout mengingati cups daripada render di mana ia dicipta. Anda akan membaiki masalah itu dalam latihan 2.
Klik +1 cup dan buka Console: variable itu naik, tetapi nombor besar kekal 0.
Gantikan let cups = 0 dengan state: const [cups, setCups] = useState(0). Kemudian ubah addCup supaya memanggil setCups(cups + 1). Buat perkara yang sama di dalam addCupLater buat masa ini (setCups(cups + 1) di dalam timeout) — anda akan melihatnya semula dalam latihan seterusnya.
Semakan
- Kaunter bermula pada 0
- Klik "+1 cup" mengemas kini skrin
Uji kefahaman
Apa yang anda pelajari
- ✓
const [value, setValue] = useState(initial)memberi component ingatan antara render. - ✓Memanggil setter menjalankan semula component dengan nilai baharu; React kemudian mengemas kini DOM.
- ✓Jangan mutasi state — buat array/objek baharu dengan spread:
[...list, x],{ ...obj, key: v }. - ✓Bila nilai seterusnya bergantung pada nilai sebelumnya, guna
setValue((prev) => …).
Output konsol daripada kod anda akan dipaparkan di sini.