Mundarija (27)
- Bu darsda
- 1. Nega bu kerak?
- 2. Snapshot: har chizish — o'z surati
- 2.1 State — chizish paytidagi qiymat
- 2.2 Surat taymerda ham o'zgarmaydi
- 3. Batching: bir nechta yangilash — bitta chizish
- 3.1 Ishlovchi tugaguncha kutiladi
- 3.2 Automatic batching: taymer va promise'da ham
- 4. Updater funksiya
- 4.1 setCount(c => c + 1)
- 4.2 Qiymat va funksiya aralash
- 4.3 Qachon updater kerak
- 5. Tuzoq: eskirgan closure taymerda
- 6. flushSync — "hozir chiz"
- 7. Vazifalar qadami: forma ichida snapshot va batching
- 7.1 ozgardi() dagi xato — shu chizishning surati
- 7.2 yuborildi() — ikki setter, bitta chizish
- 7.3 Nega setTakliflar(prev => …) emas
- 8. Ko'p uchraydigan xatolar
- 9. Mashqlar
- 1-mashq (oson): navbatni hisoblang
- 2-mashq (o'rta): savat hisoblagichi
- 3-mashq (qiyin): kechiktirilgan buyurtma (TypeScript)
- 4-mashq: vazifalar ga nazar
- 10. Real ishda
- Xulosa
- Manbalar
State II: snapshot, batching va updater funksiya — nega setCount uch marta yozilsa ham 1 qo'shiladi
Qisqacha: Har chizishda state — qotgan surat (snapshot): shu chizishdagi ishlovchilar
countning aynan o'sha qiymatini ko'radi. Setter —setCount(count + 1)— o'zgaruvchini o'zgartirmaydi — u React navbatiga "keyingi chizishda shunday bo'lsin" deb yozadi. React ishlovchi tugaguncha kutib, hamma yangilashni bitta chizishda bajaradi (batching). Shuning uchunsetCount(count + 1)uch marta — baribir +1. Oldingi qiymatdan hisoblash kerak bo'lsa — updater funksiya:setCount(c => c + 1). Uch marta yozilsa — +3.
Bu darsda
- State nega "qotgan surat" ekanini va setter'dan keyin o'zgaruvchi nega eski qolishini tushuntira olasiz.
- React bir nechta yangilashni bitta chizishga qanday yig'ishini (batching) bilasiz.
- Updater funksiyani qachon ishlatishni va navbat qanday hisoblanishini bilasiz.
- Taymer ichidagi eskirgan closure (stale closure) tuzog'ini taniysiz va tuzatasiz.
flushSyncnima qilishini va nega uni kam ishlatish kerakligini bilasiz.
Oldin bilishingiz kerak: State I: useState — komponent xotirasi, Closure: funksiya o'z muhitini eslab qoladi, Closure tuzoqlari.
1. Nega bu kerak?
Sardor «Bahor» kassasiga "+3 osh" tugmasini qo'shdi — katta oilalar uchun. Mantiq oddiy tuyuldi: uch marta qo'sh.
import { useState } from "react";
function App() {
const [count, setCount] = useState(0);
console.log("chizildi, count =", count);
function addThree() {
setCount(count + 1);
setCount(count + 1);
setCount(count + 1);
}
return (
<>
<p>Osh: {count}</p>
<button onClick={addThree}>+3</button>
</>
);
}Konsolda:
chizildi, count = 0
chizildi, count = 1Ekranda:
Osh: 1
+3Tugma bosildi — osh 1. Uch emas. Va komponent faqat bir marta qayta chizildi, uch marta emas. State I darsida ozgina sezgandik: setter'dan keyin count eski qolardi. Bugun bu xulqni oxirigacha tushunamiz — u xato emas, React'ning eng muhim g'oyalaridan biri.
Hayotiy o'xshatish: ofitsiant buyurtma varaqasi. Mijoz bir zumda uch narsa aytadi: "osh qo'shing, choy qo'shing, nonni olib tashlang". Ofitsiant har gapdan keyin oshxonaga yugurmaydi. U hammasini varaqaga yozadi va oxirida bir marta olib boradi. Oshxona varaqani tartib bilan o'qib, bitta tayyor buyurtma chiqaradi.
2. Snapshot: har chizish — o'z surati
2.1 State — chizish paytidagi qiymat
Pure komponentlar darsidan: chizish — React komponent funksiyangizni chaqiradi. Har chaqiruvda useState shu chizish uchun qiymat beradi va u const ga tushadi. Bu chaqiruv ichidagi hamma narsa shu qiymatni ko'radi: JSX ham, ishlovchilar ham (closure).
addThree ni React ko'zi bilan "o'qib chiqamiz" — count o'rniga uning shu chizishdagi qiymatini qo'yib:
// birinchi chizishning ishlovchisi — count = 0
function addThree() {
setCount(0 + 1); // keyingi chizishda 1 bo'lsin
setCount(0 + 1); // keyingi chizishda 1 bo'lsin
setCount(0 + 1); // keyingi chizishda 1 bo'lsin
}Uchala qatorda count — 0. Setter count ni o'zgartirmaydi: u boshqa chizishning boshqa const iga tegolmaydi. Uch marta "1 bo'lsin" deyildi — natija 1.
| Qadam | count (surat) |
React navbati | Ekranda |
|---|---|---|---|
| birinchi chizish | 0 | — | Osh: 0 |
setCount(0 + 1) |
0 | 1 |
Osh: 0 |
setCount(0 + 1) |
0 | 1, 1 |
Osh: 0 |
setCount(0 + 1) |
0 | 1, 1, 1 |
Osh: 0 |
| ishlovchi tugadi → qayta chizish | 1 | — | Osh: 1 |
2.2 Surat taymerda ham o'zgarmaydi
Snapshot kelajakdagi kodda ham saqlanadi. Buyurtma yuborish tugmasi: bosilgandan 100 ms o'tib, "Yuborildi: …" chiqadi. Foydalanuvchi esa shu orada maydonni o'zgartirdi:
import { useState } from "react";
function App() {
const [text, setText] = useState("");
function handleSend() {
setTimeout(() => {
console.log("Yuborildi:", text);
}, 100);
}
return (
<>
<input
aria-label="Matn"
value={text}
onChange={(event) => setText(event.target.value)}
/>
<button onClick={handleSend}>Yubor</button>
</>
);
}Konsolda:
Yuborildi: OshEkranda:
YuborBlok "Osh" deb yozib, tugmani bosdi va darhol "Choy" deb yozdi. Taymer ishlaganida maydonda allaqachon "Choy" turgan edi. Lekin chiqdi "Osh" — bosilgan paytdagi surat. handleSend "Osh" li chizishda yaratilgan va o'shaning text ini eslab qolgan. Ko'pincha aynan shu kerak: foydalanuvchi yuborgan narsa yuboriladi, keyin yozgani emas. Xuddi pochtaga tashlangan xatni orqaga qaytarib, matnini o'zgartirib bo'lmagandek.
Tekshirib ko'ring:
setCount(count + 5); console.log(count);—count10 bo'lsa, konsolda nima chiqadi? Keyingi chizishda-chi?
Javob
Konsolda — 10: bu chizishning surati o'zgarmaydi. Keyingi chizishda count — 15. Setter "keyingi chizish uchun" yozadi, hozirgi o'zgaruvchiga tegmaydi.
3. Batching: bir nechta yangilash — bitta chizish
3.1 Ishlovchi tugaguncha kutiladi
«Nega bu kerak?» dagi konsolda "chizildi" faqat ikki marta chiqdi: birinchi chizish va bosishdan keyingi bitta. Uchta setter — bitta chizish. React ishlovchi ichidagi hamma yangilashni yig'adi va ishlovchi tugagach bir marta chizadi. Bu batching (partiyalab yangilash) deyiladi — Ketma-ket va parallel bajarish darsidagi "partiyalab" g'oyasining React'dagi ko'rinishi.
Nega yaxshi:
- Tezlik. O'nta setter — o'nta chizish emas, bitta.
- Chala holat yo'q. Ikki state birga o'zgarsa (masalan,
isSavingvaerror), ekranda "biri yangi, biri eski" oraliq kadr ko'rinmaydi.
3.2 Automatic batching: taymer va promise'da ham
React 18 dan beri batching hamma joyda: setTimeout, fetch().then(), await dan keyin ham. Bu "automatic batching" deyiladi:
import { useState } from "react";
function App() {
const [dish, setDish] = useState("—");
const [price, setPrice] = useState(0);
console.log("chizildi:", dish, price);
function handleClick() {
setTimeout(() => {
setDish("Manti");
setPrice(30000);
}, 10);
}
return <button onClick={handleClick}>Ikkalasi</button>;
}Konsolda:
chizildi: — 0
chizildi: Manti 30000Ekranda:
IkkalasiTaymer ichida ikki setter — bitta chizish. React 17 va undan oldin bu yerda ikki chizish bo'lardi: oraliq kadrda "Manti, 0 so'm". Eski maqolalarda "taymerda batching yo'q" degan gapni uchratsangiz — bu React 18 dan oldingi davr.
4. Updater funksiya
4.1 setCount(c => c + 1)
"+3" tugmasini tuzatamiz. Setter'ga qiymat o'rniga funksiya beramiz:
import { useState } from "react";
function App() {
const [count, setCount] = useState(0);
function addThree() {
setCount((c) => c + 1);
setCount((c) => c + 1);
setCount((c) => c + 1);
}
return (
<>
<p>Osh: {count}</p>
<button onClick={addThree}>+3</button>
</>
);
}Ekranda:
Osh: 3
+3(c) => c + 1 — updater funksiya (yangilovchi). U "1 bo'lsin" demaydi, "oldingisiga 1 qo'sh" deydi. React navbatdagi funksiyalarni ketma-ket bajaradi: har biri oldingisining natijasini oladi.
| Navbatdagi | c (kirish) |
Natija |
|---|---|---|
c => c + 1 |
0 | 1 |
c => c + 1 |
1 | 2 |
c => c + 1 |
2 | 3 |
Navbat chizish paytida, useState chaqirilganda hisoblanadi. Shuning uchun updater toza bo'lishi kerak (Pure komponentlar): StrictMode uni ham ikki marta chaqiradi.
4.2 Qiymat va funksiya aralash
Navbatda qiymat ham, funksiya ham bo'lishi mumkin. Qiymat — "shu bo'lsin" (oldingisini e'tiborsiz qoldiradi), funksiya — "oldingisidan hisobla":
import { useState } from "react";
function App() {
const [n, setN] = useState(0);
return (
<>
<p>{n}</p>
<button
onClick={() => {
setN(n + 5);
setN((x) => x + 1);
setN(42);
setN((x) => x * 2);
}}
>
Hisobla
</button>
</>
);
}Ekranda:
84
Hisobla| Navbatdagi | Kirish | Natija |
|---|---|---|
n + 5 → qiymat 5 |
0 | 5 |
x => x + 1 |
5 | 6 |
qiymat 42 |
6 | 42 |
x => x * 2 |
42 | 84 |
Birinchi qatordagi n — surat, 0. Qiymat 42 oldingi hamma narsani "o'chirib" yuboradi. Oxirgi updater esa 42 dan hisoblaydi.
flowchart LR
A["0"] -- "5 qiymati" --> B["5"]
B -- "x + 1" --> C["6"]
C -- "42 qiymati" --> D["42"]
D -- "x * 2" --> E["84"]Diagrammada navbat chapdan o'ngga o'qiladi: har o'q — bitta setter. Qiymat oldingi raqamga qaramaydi, funksiya esa aynan undan boshlaydi.
4.3 Qachon updater kerak
Har doim emas. Qoida:
- Yangi qiymat oldingisidan hisoblanadi va bir ishlovchida bir necha marta yangilanadi — updater:
setCount(c => c + 1). - Yangi qiymat kechiktirilgan kodda (taymer,
await) eskidan hisoblanadi — updater (pastdagi tuzoq). - Yangi qiymat oldingisiga bog'liq emas — oddiy qiymat:
setName(event.target.value),setError(null).
Nomlash odati: parametr — state nomining birinchi harfi (c — count) yoki prev + nom (prevCount). Ba'zilar har doim updater yozadi — bu ham xato emas, faqat kod uzunroq.
Tekshirib ko'ring:
setGuests(guests + 1); setGuests((g) => g + 1);—guests2 bo'lsa, natija?
Javob
- Navbat: qiymat
2 + 1 = 3, keyin updater3 + 1 = 4. Birinchi qatordagiguests— surat (2), ikkinchisi esa navbatdagi oldingi natijadan (3) boshlaydi.
5. Tuzoq: eskirgan closure taymerda
Snapshot ba'zan foydali («Surat taymerda ham o'zgarmaydi» bo'limi), ba'zan esa xato manbai. Choyxonada "3 soniyadan keyin choy qo'shish" tugmasi bor. Mijoz uni tez-tez uch marta bosdi:
import { useState } from "react";
function App() {
const [plain, setPlain] = useState(0);
const [safe, setSafe] = useState(0);
function handleClick() {
setTimeout(() => {
setPlain(plain + 1); // ❌ surat: bosilgandagi qiymat
setSafe((s) => s + 1); // ✅ navbatdagi oldingi qiymat
}, 300);
}
return (
<>
<p>
Oddiy: {plain}, updater: {safe}
</p>
<button onClick={handleClick}>+1 keyin</button>
</>
);
}Ekranda:
Oddiy: 1, updater: 3
+1 keyinUch bosish birinchi taymer ishlashidan oldin bo'ldi. Uchala ishlovchi plain = 0 li suratni ko'rgan: uchala taymer "1 bo'lsin" dedi. Updater esa suratga qaramaydi — u React navbatidagi haqiqiy oldingi qiymatdan hisoblaydi. Bu Closure tuzoqlari darsidagi "eskirgan closure" (stale closure) ning React'dagi ko'rinishi. U effektlarda ham uchraydi — useEffect II va useEffectEvent darslarida qaytamiz.
6. flushSync — "hozir chiz"
Batching'ning bitta "kamchiligi" bor: setter'dan keyin DOM hali eski. Ko'pincha bu muammo emas — keyingi chizishni React o'zi qiladi. Lekin ba'zan DOM'ga darhol qarash kerak: yangi qo'shilgan elementga scroll qilish, uning o'lchamini olish. Buning uchun react-dom dagi flushSync:
import { useState } from "react";
import { flushSync } from "react-dom";
function App() {
const [items, setItems] = useState(["Osh"]);
function add() {
setItems([...items, "Manti"]);
const before = document.querySelectorAll("li").length;
console.log("flushSync'siz:", before);
flushSync(() => {
setItems([...items, "Manti", "Choy"]);
});
const after = document.querySelectorAll("li").length;
console.log("flushSync bilan:", after);
}
return (
<>
<ul>
{items.map((item) => (
<li key={item}>{item}</li>
))}
</ul>
<button onClick={add}>Qo'shish</button>
</>
);
}Konsolda:
flushSync'siz: 1
flushSync bilan: 3Ekranda:
Osh
Manti
Choy
Qo'shishBirinchi setItems dan keyin DOM'da hali bitta <li>. Lekin flushSync ichidagi yangilashni (va navbatda kutayotganini ham) darhol chizadi — keyingi qatorda uchta <li>. Bizning vazifalar dagi render.tsx da ham aynan shu sabab bilan ishlatilgan (Ro'yxatlar va key). U yerda vanilla kod ro'yxat chizilgandan keyingi qatorda yangi qatorlarga qaraydi.
flushSync — kam holat uchun vosita:
- batching'ni buzadi va tezlikni pasaytiradi;
- chizish paytida chaqirilsa, React ogohlantiradi;
- odatda kerak emas: DOM bilan ishlash uchun to'g'ri joy — ref'lar va effektlar.
7. Vazifalar qadami: forma ichida snapshot va batching
Bu darsda vazifalar kodi o'zgarmaydi. Lekin State I da yozgan YangiVazifaForma ikkala g'oyani ham ishlatadi — uni bugungi ko'z bilan qayta o'qiymiz.
7.1 ozgardi() dagi xato — shu chizishning surati
// Maydon o'zgardi (harf, teg tanlandi): qoralama, takliflar, xato
function ozgardi(maydon: HTMLInputElement) {
onYoz(maydon.value);
const kursor = maydon.selectionStart ?? maydon.value.length;
setTakliflar(takliflarniTop(joriyTeg(maydon.value, kursor)));
// Xato ko'rsatilgan bo'lsa — tuzatilgani zahoti yo'qolsin
if (xato !== null && xatoniTop(maydon.value.trim()) === null) {
setXato(null);
}
}xato — state, ozgardi uni o'qiydi. Qaysi qiymatini? ozgardi funksiyasi qaysi chizishda yaratilgan bo'lsa — o'shaning suratini. Bu yerda bu to'g'ri, chunki React har chizishda maydonning onInput iga yangi ozgardi ni beradi. Foydalanuvchi har harf yozganda oxirgi chizishning ishlovchisi ishlaydi — xato doim yangi.
Ikkinchi narsa — maydon qiymati maydon.value dan, ya'ni DOM dan o'qiladi, state'dan emas. Maydon uncontrolled: matn state'da yo'q, uning surati ham yo'q. Shuning uchun ozgardi doim hozirgi matnni ko'radi. Snapshot faqat state va props'ga tegishli.
7.2 yuborildi() — ikki setter, bitta chizish
case "qoshildi":
setXato(null);
setTakliflar([]);Ikki setter ketma-ket. Batching tufayli forma bir marta qayta chiziladi: xato ham, takliflar ham bir kadrda yo'qoladi. Updater kerak emas: yangi qiymatlar (null, []) oldingisiga bog'liq emas («Qachon updater kerak» bo'limi).
7.3 Nega setTakliflar(prev => …) emas
setTakliflar(takliflarniTop(…)) ham oldingi takliflarga qaramaydi — u har safar joriy matndan qayta hisoblanadi. Agar qoida "har harfda bitta taklif qo'shilsin" bo'lganda edi, updater kerak bo'lardi: setTakliflar((t) => [...t, yangi]). Massivni shunday yangilash usullari — keyingi darsda.
8. Ko'p uchraydigan xatolar
| Belgi | Sabab | Davosi |
|---|---|---|
| "+3" bosilganda +1 | setX(x + 1) × 3 — bitta surat |
setX(x => x + 1) |
| setter'dan keyin eski qiymat | snapshot — xato emas | yangi qiymatni o'zgaruvchiga oling: const next = x + 1 |
| taymer eski raqamni yozdi | eskirgan closure | updater funksiya |
| setter'dan keyin DOM eski | batching | odatda kerak emas; zarur bo'lsa flushSync |
updater ichida fetch, console.log ikki marta |
updater ham render'da, StrictMode | updater toza bo'lsin |
| "taymerda ikki marta chizildi" (eski maqola) | React 17 gacha | React 18+ automatic batching |
9. Mashqlar
Mashqlar kurs/mashqlar/17/13-snapshot/ da. Har yechimni «Ishga tushir» bilan sinang.
1-mashq (oson): navbatni hisoblang
score 10 bo'lganda tugma bosildi. Ekranda nima chiqadi? Ishga tushirmasdan hisoblang.
import { useState } from "react";
function App() {
const [score, setScore] = useState(10);
return (
<>
<p>{score}</p>
<button
onClick={() => {
setScore(score + 1);
setScore((s) => s * 2);
setScore(score + 3);
setScore((s) => s - 1);
}}
>
Bos
</button>
</>
);
}- Natija:
Yechim
Ekranda:
12
BosNavbat: qiymat 10 + 1 = 11 → updater 11 * 2 = 22 → qiymat 10 + 3 = 13 (surat — 10!) → updater 13 - 1 = 12. Uchinchi qatordagi score — surat, shuning uchun 22 ga e'tibor bermadi.
2-mashq (o'rta): savat hisoblagichi
Cart komponentini yozing: state count (0). Uch tugma: "+1", "+2" (ichida ikki marta +1 — updater bilan), "Tozalash". Har bosishdan keyin komponent necha marta chizilganini konsolga yozing (console.log("chizildi", count)). Blok: "+2", "+1", "Tozalash", "+2". Ekranda "Savat: 2", konsolda — beshta "chizildi" (birinchi chizish va to'rt bosish — har biri bitta chizish).
Yechim
import { useState } from "react";
function Cart() {
const [count, setCount] = useState(0);
console.log("chizildi", count);
function addTwo() {
setCount((c) => c + 1);
setCount((c) => c + 1);
}
return (
<>
<p>Savat: {count}</p>
<button onClick={() => setCount((c) => c + 1)}>+1</button>
<button onClick={addTwo}>+2</button>
<button onClick={() => setCount(0)}>Tozalash</button>
</>
);
}
function App() {
return <Cart />;
}Konsolda:
chizildi 0
chizildi 2
chizildi 3
chizildi 0
chizildi 2Ekranda:
Savat: 2
+1+2Tozalash"+2" ichida ikki setter — lekin konsolda bitta "chizildi": batching. "Tozalash" — oddiy qiymat 0: u oldingisiga bog'liq emas, updater shart emas.
3-mashq (qiyin): kechiktirilgan buyurtma (TypeScript)
Oshxona buyurtmani 300 ms da tasdiqlaydi (setTimeout bilan taqlid). .tsx da yozing:
- state:
confirmed: number(tasdiqlangan buyurtmalar soni) valog: readonly string[](tasdiq xabarlari); - "Buyurtma" tugmasi har bosilganda taymer qo'yadi; taymer
confirmedni 1 ga oshiradi valogga"№N tasdiqlandi"qo'shadi (N — tasdiq tartib raqami); - tez-tez uch marta bosilsa ham, natija "Tasdiqlangan: 3" va uchta turli xabar bo'lsin.
Ishora: ikkala state ham updater bilan. log ga qo'shish — yangi massiv: (l) => [...l, matn] (Spread). N ni qayerdan olish mumkin? confirmed ning updater'idagi qiymatidan — lekin updater toza bo'lishi kerak, ichida boshqa setter chaqirmang. Oddiyroq yo'l: N = log uzunligi + 1, log ning o'z updater'ida.
Yechim
import { useState } from "react";
export default function App() {
const [confirmed, setConfirmed] = useState(0);
const [log, setLog] = useState<readonly string[]>([]);
function handleOrder() {
setTimeout(() => {
setConfirmed((c) => c + 1);
setLog((l) => [...l, `№${l.length + 1} tasdiqlandi`]);
}, 300);
}
return (
<>
<button onClick={handleOrder}>Buyurtma</button>
<p>Tasdiqlangan: {confirmed}</p>
<ul>
{log.map((line) => (
<li key={line}>{line}</li>
))}
</ul>
</>
);
}Ekranda:
Buyurtma
Tasdiqlangan: 3
№1 tasdiqlandi
№2 tasdiqlandi
№3 tasdiqlandisetConfirmed(confirmed + 1) yozilganda — uchala taymer ham 0 li suratni ko'rib, "Tasdiqlangan: 1" bo'lardi. log uchun ham shu: [...log, …] — har safar bo'sh massivdan, oxirida bitta xabar. Updater ikkalasini ham navbatdagi haqiqiy oldingi qiymatdan hisoblaydi. key={line} — xabarlar raqam bilan noyob.
4-mashq: vazifalar ga nazar
Kod o'zgarmaydi. src/YangiVazifaForma.tsx dagi tegniQoy funksiyasini o'qing. U maydonga tegni qo'yadi va oxirida ozgardi(maydon) ni chaqiradi. Savol: ozgardi ichidagi xato qaysi chizishning suratini ko'radi? Agar tegniQoy dan oldin setXato(null) chaqirilganda edi, ozgardi ichida xato nima bo'lardi?
Yechim
tegniQoy — teg tugmasining onClick i, u oxirgi chizishda yaratilgan. Ichida chaqirilgan ozgardi ham o'sha chizishniki — xato o'sha chizishning surati. setXato(null) oldinroq chaqirilsa ham, ozgardi ichida xato eski qiymat bo'lib qolardi: setter faqat keyingi chizishni o'zgartiradi. Bu yerda bu zararsiz — ozgardi xatoni faqat null ga tozalaydi, ikki marta tozalash hech narsani buzmaydi. Lekin "setter'dan keyin yangi qiymatga tayanish" har doim xato ekanini eslang.
10. Real ishda
- Hisoblagichlar, savat, "like" — updater bilan yoziladi:
setLikes(l => l + 1). Tez-tez bosish va sekin internetda ham to'g'ri ishlaydi. - Formalar — bir nechta setter (
setSaving,setError,setData) ketma-ket chaqiriladi va batching ularni bitta kadrga yig'adi. - Kod ko'rigida: "taymer ichida
setX(x + 1)— updater ishlating", "flushSyncnega kerak?". - Intervyu savollari: "
setStatesinxronmi yoki asinxronmi?". To'g'ri javob: chaqiruvning o'zi sinxron, lekin qayta chizish navbatga qo'yiladi va o'zgaruvchi shu chizishda o'zgarmaydi. Yana: "Automatic batching nima?", "Updater funksiya qachon kerak?".
Xulosa
- State — har chizishning qotgan surati; setter shu chizishdagi o'zgaruvchini o'zgartirmaydi.
- Setter React navbatiga yozadi; React ishlovchi tugagach hammasini bitta chizishda bajaradi — batching (React 18+ da taymer va promise'da ham).
- Oldingi qiymatdan hisoblash — updater:
setX(x => x + 1); navbat tartib bilan, har biri oldingisining natijasidan. - Taymer va
awaitdan keyin eski suratdan hisoblash — eskirgan closure; davosi — updater. flushSync— "hozir chiz", kam holatda; DOM uchun odatda ref va effektlar.vazifalarformasidaozgardixatoning suratini o'qiydi,yuborildidagi ikki setter bitta chizishda bajariladi.
Keyingi dars: State III: obyekt va massivlarni immutable yangilash — state'dagi obyekt va massivni nega joyida o'zgartirib bo'lmasligini ko'ramiz va vazifalar ga o'zgarmas ro'yxat va amallar.ts ni qo'shamiz.
Manbalar
- React: "State as a Snapshot" — react.dev/learn/state-as-a-snapshot
- React: "Queueing a Series of State Updates" — react.dev/learn/queueing-a-series-of-state-updates
- React 18 blogi: "Automatic Batching" (2022-03-29) — react.dev/blog/2022/03/29/react-v18
- React:
flushSync— react.dev/reference/react-dom/flushSync
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!