Mundarija (30)
- Bu darsda
- 1. Nega bu kerak?
- 2. Muammo: shartli chizish state'ni yo'qotadi
- 2.1 Tablar — oddiy usulda
- 2.2 Eski yechimlar va ularning narxi
- 3. <Activity>
- 3.1 State saqlanadi
- 3.2 Yashirinda nima bo'ladi
- 4. Effektlar to'xtaydi
- 4.1 Konsolda
- 4.2 Nima to'xtamaydi
- 5. Oldindan chizish (prerender)
- 5.1 Yashirin boshlansa — fonda chiziladi
- 5.2 Prerender'ning narxi
- 6. Qaysi biri qachon
- 7. Vazifalar qadami: statistika paneli — <Activity> (holat 11)
- 7.1 Saqlanadigan narsa
- 7.2 StatistikaPaneli.tsx
- 7.3 CSP va display: none
- 7.4 Haqiqiy brauzerda
- 7.5 Commit
- 8. Ko'p uchraydigan xatolar
- 9. Mashqlar
- 1-mashq (oson): nima bo'ladi?
- 2-mashq (o'rta): savat soni yo'qolmasin
- 3-mashq (qiyin): taymer yashirinda to'xtasin
- 4-mashq: Vazifalar qadami
- 10. Real ishda
- Xulosa
- Manbalar
React Activity: yashirin UI holatini saqlash, effektlarni to'xtatish va oldindan chizish
Qisqacha:
<Activity mode="hidden">— ichidagi UI'ni o'chirmasdan yashiradi. Shartli chizishda ({open && <Panel />}) yopilgan komponent butunlay yo'qoladi. U bilan state, yozilgan matn va scroll ham ketadi.<Activity>esa uni DOM'dadisplay: nonebilan qoldiradi va state'ni saqlaydi. Lekin effektlarini to'xtatadi (cleanup ishlaydi).mode="visible"bo'lganda effektlar qayta ulanadi, ekran esa darhol — qayta yuklashsiz. Boshidanoqhiddenbo'lgan Activity'ni React fonda, eng past ustuvorlikda chizib qo'yadi (prerender). Keyingi ekran tayyor turadi — lekin bu ish ham, kod ham pulsiz emas.ActivityReact 19.2 dan barqaror (import { Activity } from "react").
Bu darsda
- Tab almashganda state yo'qolishini ko'rasiz va
<Activity>bilan uni saqlaysiz. - Yashirin holatda effektlar to'xtashini konsolda kuzatasiz va nega bu muhimligini tushuntira olasiz.
- Oldindan chizish (prerender) qanday ishlashini va qachon zararli ekanini bilasiz.
<Activity>, shartli chizish, CSS bilan yashirish vakey— to'rtalasini solishtirasiz.vazifalardagi statistika panelini<Activity>ga o'tkazasiz va nega u birinchi ochilishdan keyin qurilishini tushunasiz.
Oldin bilishingiz kerak: State'ning saqlanishi va key, Effekt hayot sikli, Suspense, lazy.
1. Nega bu kerak?
«Bahor» saytida taom sahifasida uch tab bor: «Tarkibi», «Sharhlar», «Buyurtma». Mehmon «Buyurtma» tabida "piyozsiz, achchiq bo'lsin" deb uzun izoh yozdi. Keyin «Sharhlar» ni ochib, boshqalar nima deganini o'qidi. Qaytib keldi — izoh yo'q. Yana yozishi kerak.
Sardor tablarni shunday yozgan: {tab === "order" && <OrderForm />}. State'ning saqlanishi darsidan bilasiz: komponent daraxtdan olib tashlansa, React uning state'ini ham tashlaydi. Tab yopildi — OrderForm yo'q — izoh yo'q.
Ikkinchi muammo — tezlik. «Sharhlar» tabi har ochilishda serverdan qayta yuklanadi, scroll boshiga qaytadi. Mehmon 30-sharhni o'qiyotgan edi — yana boshidan.
Hayotiy o'xshatish: telefondagi ilovalar. Telegram'dan chiqib, kamerani ochasiz. Telegram yopilmaydi — orqa fonda "uxlaydi". Yozib turgan xabaringiz joyida, chat o'sha joyda. Lekin uxlab yotgan ilova batareyani yemaydi: ovozli qo'ng'iroq, GPS — to'xtatilgan. Qaytsangiz — darhol uyg'onadi. <Activity mode="hidden"> — aynan shu "orqa fon".
2. Muammo: shartli chizish state'ni yo'qotadi
2.1 Tablar — oddiy usulda
import { useState } from "react";
function OrderForm() {
const [note, setNote] = useState("");
return (
<p>
<label>
Izoh{" "}
<input
value={note}
onChange={(e) => setNote(e.target.value)}
/>
</label>
</p>
);
}
function Reviews() {
return <p>Sharhlar: "Osh zo'r!" — Malika</p>;
}
export default function App() {
const [tab, setTab] = useState("order");
function showNote() {
const input = document.querySelector("input");
console.log("izohda:", JSON.stringify(input.value));
}
return (
<div>
<button onClick={() => setTab("order")}>Buyurtma</button>{" "}
<button onClick={() => setTab("reviews")}>Sharhlar</button>{" "}
<button onClick={showNote}>Izoh?</button>
{tab === "order" && <OrderForm />}
{tab === "reviews" && <Reviews />}
</div>
);
}Konsolda:
izohda: """Piyozsiz" yo'qoldi. «Sharhlar» bosilganda OrderForm daraxtdan chiqdi (unmount), qaytganda — yangi OrderForm, yangi state, bo'sh maydon.
2.2 Eski yechimlar va ularning narxi
Ilgari bu muammoni uch yo'l bilan hal qilishardi:
| Yo'l | Nima qiladi | Narxi |
|---|---|---|
| state'ni ko'tarish (state'ni ko'tarish) | izoh App da saqlanadi |
har tabning hamma state'ini yuqorida yig'ish; scroll, fokus baribir yo'qoladi |
CSS bilan yashirish (hidden, display: none) |
komponent doim chizilgan, faqat ko'rinmaydi | yashirin tabning effektlari ishlayveradi: taymerlar, obunalar, so'rovlar |
localStorage ga saqlash |
qaytganda tiklanadi | qo'shimcha kod, faqat oddiy qiymatlar uchun |
Ikkinchi yo'l eng yaqin — lekin uning muammosi jiddiy. Yashirin «Sharhlar» tabi har 10 soniyada serverdan yangi sharh so'rasa, u ko'rinmasa ham so'rayveradi. O'nta yashirin tab — o'nta behuda so'rov oqimi. <Activity> — "CSS bilan yashirish, lekin effektlarni to'xtatib".
3. <Activity>
3.1 State saqlanadi
import { Activity, useState } from "react";
function OrderForm() {
const [note, setNote] = useState("");
return (
<p>
<label>
Izoh{" "}
<input
value={note}
onChange={(e) => setNote(e.target.value)}
/>
</label>
</p>
);
}
function Reviews() {
return <p>Sharhlar: "Osh zo'r!" — Malika</p>;
}
export default function App() {
const [tab, setTab] = useState("order");
function showNote() {
const input = document.querySelector("input");
console.log("izohda:", JSON.stringify(input.value));
}
return (
<div>
<button onClick={() => setTab("order")}>Buyurtma</button>{" "}
<button onClick={() => setTab("reviews")}>Sharhlar</button>{" "}
<button onClick={showNote}>Izoh?</button>
<Activity mode={tab === "order" ? "visible" : "hidden"}>
<OrderForm />
</Activity>
<Activity mode={tab === "reviews" ? "visible" : "hidden"}>
<Reviews />
</Activity>
</div>
);
}Konsolda:
izohda: "Piyozsiz"Ekranda:
Buyurtma Sharhlar Izoh?
Izoh"Piyozsiz" joyida. «Sharhlar» ochiq paytda (ekran tekshirdi) OrderForm ko'rinmadi, lekin daraxtdan chiqmadi. «Ekranda» bo'limida sharhlar yo'q: yashirin Activity ichi display: none — sinov vositasi ham, foydalanuvchi ham uni ko'rmaydi.
mode faqat ikki qiymat oladi: "visible" (standart) va "hidden". Kodda o'zgargan narsa — {shart && …} o'rniga <Activity mode={shart ? "visible" : "hidden"}>.
3.2 Yashirinda nima bo'ladi
Shartli chizish (false) |
CSS hidden |
<Activity mode="hidden"> |
|
|---|---|---|---|
| DOM | yo'q | bor | bor, display: none |
| state | yo'qoladi | saqlanadi | saqlanadi |
| effektlar | cleanup, keyin yo'q | ishlayveradi | cleanup — to'xtatiladi |
| props o'zgarsa qayta chizish | — | odatdagidek | fonda, eng past ustuvorlikda |
| qaytganda | yangidan, effektlar yangidan | darhol | darhol, effektlar qayta ulanadi |
Oxirgi ustun — <Activity> ning mohiyati: DOM va state — saqlanadi, effektlar — to'xtaydi.
4. Effektlar to'xtaydi
4.1 Konsolda
«Sharhlar» tabi yangi sharhlarni kuzatib turadi — real ilovada bu WebSocket yoki har 10 soniyada so'rov bo'lardi (Effekt). Effektni log bilan kuzatamiz:
import { Activity, useEffect, useState } from "react";
function Reviews() {
useEffect(() => {
console.log("sharhlar kuzatuvi: ulandi");
return () => console.log("sharhlar kuzatuvi: uzildi");
}, []);
return <p>Sharhlar: 5 ta</p>;
}
export default function App() {
const [tab, setTab] = useState("menu");
return (
<div>
<button onClick={() => setTab("menu")}>Menyu</button>{" "}
<button onClick={() => setTab("reviews")}>Sharhlar</button>
<Activity mode={tab === "menu" ? "visible" : "hidden"}>
<p>Osh, lag'mon, manti</p>
</Activity>
<Activity mode={tab === "reviews" ? "visible" : "hidden"}>
<Reviews />
</Activity>
</div>
);
}Konsolda:
sharhlar kuzatuvi: ulandi
sharhlar kuzatuvi: uzildi
sharhlar kuzatuvi: ulandiOchilishda «Sharhlar» yashirin — effekt ulanmadi (konsol bo'sh). Ochildi — ulandi. Yopildi — uzildi (cleanup). Yana ochildi — qayta ulandi. Yashirin paytda kuzatuv yo'q: so'rov ketmaydi, batareya sarflanmaydi.
E'tibor bering: bu xuddi StrictMode dagi "setup → cleanup → setup" sinovi. StrictMode effektlaringiz shunga tayyorligini oldindan tekshirgan edi. Cleanup'i to'g'ri yozilgan effekt <Activity> ichida ham to'g'ri ishlaydi. Cleanup'i yo'q effekt esa har ochilishda yangi ulanish qo'shadi — Effekt hayot sikli dagi oqish.
4.2 Nima to'xtamaydi
<Activity> faqat React effektlarini to'xtatadi. DOM'ning o'z xulqi davom etadi:
- Yashirin
<video>yoki<audio>o'ynashda davom etadi —display: noneovozni o'chirmaydi. Effekt cleanup'idapause()chaqiring. - Effektdan tashqarida (modul darajasida) boshlangan
setIntervalto'xtamaydi — React u haqda bilmaydi. - State saqlanadi — bu ham xotira. Yuzta yashirin tab — yuzta komponent daraxti xotirada.
function VideoTab({ src }) {
const ref = useRef(null);
// Yashirilganda — cleanup: video to'xtaydi
useLayoutEffect(() => {
const video = ref.current;
return () => video.pause();
}, []);
return <video ref={ref} src={src} controls />;
}React hujjati bu yerda useLayoutEffect ni tavsiya qiladi: cleanup Activity yashirilishi bilan bir vaqtda, bo'yashdan oldin ishlaydi (useLayoutEffect).
Tekshirib ko'ring: Yashirin «Sharhlar» tabining props'i o'zgarsa (masalan,
count5 dan 6 ga),Reviewsqayta chiziladimi?
Javob
Ha, lekin fonda, eng past ustuvorlikda — ko'rinib turgan qismning hamma ishi tugagach. Natija DOM'ga yoziladi (yashirin holda). Effektlar esa ishga tushmaydi. Tab ochilganda yangi count allaqachon chizilgan bo'ladi — qayta hisoblash kerak emas.
5. Oldindan chizish (prerender)
5.1 Yashirin boshlansa — fonda chiziladi
<Activity mode="hidden"> boshidanoq yashirin bo'lsa ham, React ichini chizadi — lekin faqat ko'rinadigan qism tayyor bo'lgach, eng past ustuvorlikda. Effektlar esa ishga tushmaydi:
import { Activity, useEffect, useState } from "react";
function Reviews() {
console.log("Reviews chizildi");
useEffect(() => {
console.log("Reviews effekti");
}, []);
return <p>Sharhlar: 5 ta</p>;
}
export default function App() {
const [tab, setTab] = useState("menu");
useEffect(() => {
console.log("App commit bo'ldi");
}, []);
return (
<div>
<button onClick={() => setTab("reviews")}>Sharhlar</button>
<Activity mode={tab === "reviews" ? "visible" : "hidden"}>
<Reviews />
</Activity>
</div>
);
}Konsolda:
App commit bo'ldi
Reviews chizildi
Reviews chizildi
Reviews effektiTartibga qarang:
| Qadam | Nima bo'ldi |
|---|---|
| 1 | App chizildi va commit bo'ldi — tugma ekranda |
| 2 | keyin, fonda: Reviews chizildi (yashirin), effekti — yo'q |
| 3 | «Sharhlar» bosildi: Reviews ko'rinadigan qilib qayta chizildi |
| 4 | effekt endi ishga tushdi |
Ikkinchi qadam — prerender. Foydalanuvchi tugmani ko'rgan paytda React bo'sh vaqtda keyingi tabni tayyorlab qo'ydi. Bosilganda DOM tayyor — faqat ko'rsatish qoladi.
Bu — Suspense bilan ham ishlaydi. Yashirin Activity ichidagi use(promise) yoki lazy komponent fonda yuklanishni boshlaydi. Tab ochilganda ma'lumot va kod allaqachon kelgan bo'lishi mumkin.
5.2 Prerender'ning narxi
Bepul tushlik yo'q. Fonda chizish — baribir ish: protsessor vaqti, xotira, tarmoq so'rovlari (yashirin lazy chunk'ni yuklaydi). Foydalanuvchi o'sha tabni hech ochmasa — hammasi behuda.
vazifalar kanonida aynan shu masala chiqdi. Statistika paneli — lazy chunk va og'ir hisob. Agar panel sahifa ochilishida <Activity mode="hidden"> bilan qurilsa, React uni fonda chizadi. Natijada chunk yuklanadi va 10 000 vazifa hisoblanadi — panelni hech kim ochmasa ham. Bu lazy darsidagi butun yutuqni yo'qqa chiqarardi.
Kanondagi yechim — Activity'ni birinchi ochilishdan keyin qurish:
const [ochilgan, setOchilgan] = useState(false);
// ...
{ochilgan && (
<Activity mode={ochiq ? "visible" : "hidden"}>
<BatafsilStatistika vazifalar={kechikkan} />
</Activity>
)}Birinchi ochilishgacha — hech narsa (na chunk, na hisob). Ochilgandan keyin — Activity: yopilsa yashirinadi va state saqlanadi.
| Qachon | ochilgan |
Ekranda | Fonda |
|---|---|---|---|
| sahifa ochildi | false |
tugma | hech narsa — chunk yuklanmaydi |
| 1-ochilish | true |
panel | — |
| yopildi | true |
tugma | panel DOM'da, effektlar to'xtagan |
| qayta ochildi | true |
panel darhol, tanlov saqlangan | — |
Qoida: prerender — ehtimoli yuqori keyingi ekran uchun. Ehtimoli past va og'ir narsa uchun — avval birinchi ochilish, keyin saqlash.
6. Qaysi biri qachon
flowchart TD
Q{"Yopilganda state saqlansinmi?"} -- "yo'q" --> C["Shartli chizish: {open && ...}"]
Q -- "ha" --> E{"Ichida effekt bormi?"}
E -- "yo'q, oddiy kontent" --> H["CSS hidden ham bo'ladi"]
E -- "ha" --> A["Activity"]
A --> P{"Oldindan chizish arzonmi?"}
P -- "ha, ehtimoliy keyingi ekran" --> AH["boshidan hidden"]
P -- "yo'q, og'ir yoki kamdan-kam" --> AO["1-ochilishdan keyin"]Diagrammadan tashqari yana bir vosita bor — key. U teskari ishni qiladi: state'ni ataylab tashlaydi (State'ning saqlanishi va key). Masalan, boshqa foydalanuvchi profili ochilganda forma toza bo'lsin. Activity "saqlash", key "yangilash" uchun.
Tekshirib ko'ring: Router'dagi 20 ta sahifaning hammasini
<Activity>bilan o'rab qo'yish yaxshi fikrmi?
Javob
Yo'q. Har yashirin sahifa — xotirada butun komponent daraxti va DOM. Boshidan yashirin bo'lsa — yana fonda chizish va yuklash. Bir nechta "orqaga qaytish ehtimoli yuqori" sahifa (masalan, ro'yxat → tafsilot → yana ro'yxat) uchun Activity foydali. Hammasi uchun — xotira va ish isrofi. Framework'lar (Next.js) buni o'zi hal qiladi.
7. Vazifalar qadami: statistika paneli — <Activity> (holat 11)
7.1 Saqlanadigan narsa
Activity kerakligini ko'rish uchun panelda saqlanadigan state bo'lishi kerak. Kanonda BatafsilStatistika ga «Teglar tartibi» tanlovi qo'shildi:
// Komponentning o'z state'i: panel yopilib-ochilganda saqlanadimi —
// 18/#11 (<Activity>) shuni ko'rsatadi
const [tartib, setTartib] = useState<"soni" | "alifbo">("soni");
const tanlovId = useId();
const teglar =
tartib === "soni"
? s.teglar
: s.teglar.toSorted((a, b) => (a.teg < b.teg ? -1 : 1));teglar — hosilaviy qiymat: state — faqat tanlov, tartiblangan ro'yxat har renderda hisoblanadi. toSorted — asl massivni o'zgartirmaydigan saralash (massiv metodlari). Tanlov — native <select> va <label> (useId bilan).
7.2 StatistikaPaneli.tsx
+ // Activity birinchi ochilishdan KEYIN quriladi: yashirin (hidden)
+ // holatda boshlansa, React uni fonda baribir chizadi (oldindan
+ // render) — lazy chunk va hisob sahifa ochilishida ishlab ketardi
+ const [ochilgan, setOchilgan] = useState(false); onClick={() =>
boshla(() => {
setOchiq((o) => !o);
+ setOchilgan(true);
})
}- <div
- id={panelId}
- hidden={!ochiq}
- aria-busy={eskirgan || undefined}
- >
- {ochiq && <BatafsilStatistika vazifalar={kechikkan} />}
+ <div id={panelId} aria-busy={eskirgan || undefined}>
+ {ochilgan && (
+ // hidden: ichi display: none, effektlari to'xtaydi,
+ // yangilanishlar — eng past ustuvorlikda; state joyida
+ <Activity mode={ochiq ? "visible" : "hidden"}>
+ <BatafsilStatistika vazifalar={kechikkan} />
+ </Activity>
+ )}
</div>Kanondan (diff, izohlar qayta bo'lingan). Ikki narsa o'zgardi:
hidden={!ochiq}atributi ketdi. Yashirishni endi Activity qiladi (display: none).{ochiq && …}→{ochilgan && <Activity …>}. Birinchi ochilishgacha — hech narsa, keyin — Activity.
Yashirin panel props o'zgarishini ham oladi: katak bosilsa, statistika fonda, eng past ustuvorlikda qayta hisoblanadi. Panel ochilganda — tayyor.
7.3 CSP va display: none
vazifalar qat'iy CSP ostida ishlaydi: inline stil atributlari taqiqlangan bo'lishi mumkin (Frontend xavfsizligi). Activity display: none ni qanday qo'yadi? Haqiqiy Chrome'da tekshirildi: React uni element.style orqali (CSSOM) yozadi — HTML atributi emas. CSP buzilishi — 0.
7.4 Haqiqiy brauzerda
e2e-18 (Chrome 155, natija-18-11.txt):
✅ activity: boshida «ko'pi oldin»: "#bozor"
✅ activity: alifbo tanlandi: "#aka"
✅ activity: yopildi — DOM joyida, display: none (CSSOM, CSP'ga mos): [true,"none"]
✅ activity: qayta ochildi — tanlov saqlangan (alifbo), fallback yo'q: ["alifbo","#aka",0]
✅ activity: CSP buzilishi yo'q: []Panel yopildi — DOM joyida, display: none. Qayta ochildi — tanlov "alifbo" bo'yicha qoldi, birinchi teg #aka, fallback bir marta ham ko'rinmadi.
7.5 Commit
git switch -c feat/statistika-activity
git add -A
git commitCommit (kanon): feat: statistika paneli <Activity> bilan — yopilganda holat saqlanadi. Tekshiruvlar: Vitest Tests 38 passed (38) (+1), node:test 163, lint, format, tip — toza. Brauzer — 159/159, e2e-18 — 34/34. Diff: 3 fayl, +87 −9.
Activity barqarorligi ham tekshirildi: React 19.3.0 da react paketidan oddiy eksport, @types/react 19.3.0 da ActivityProps turi bor. Eksperimental (unstable_) emas.
8. Ko'p uchraydigan xatolar
| Belgi | Sabab | Davosi |
|---|---|---|
| tab almashganda yozilgan matn yo'qoladi | {shart && …} — unmount |
<Activity mode={…}> |
| yashirin tab baribir so'rov yuboradi | CSS hidden — effektlar ishlayveradi |
<Activity> — effektlar to'xtaydi |
| har ochilishda ulanishlar ko'payadi | effektda cleanup yo'q | cleanup; StrictMode buni oldindan ko'rsatadi |
| yashirin video ovoz chiqaradi | display: none media'ni to'xtatmaydi |
layout effekt cleanup'ida pause() |
| sahifa ochilishida keraksiz chunk/hisob | boshidan hidden — prerender |
birinchi ochilishdan keyin qurish |
| xotira o'sib boradi | juda ko'p yashirin daraxt | faqat qaytish ehtimoli yuqori qismlar |
9. Mashqlar
Mashqlar kurs/mashqlar/18/11-activity/ da. Har yechimni «Ishga tushir» bilan sinang.
1-mashq (oson): nima bo'ladi?
<Activity mode="hidden"> ichidagi komponent uchun ha yoki yo'q:
- State saqlanadimi?
useEffectichidagi obuna ishlab turadimi?- DOM'da elementlar bormi?
- Boshidan
hiddenbo'lsa, komponent funksiyasi chaqiriladimi?
Yechim
- ha — daraxtdan chiqmaydi.
- yo'q — yashirilganda cleanup ishlaydi; ochilganda qayta ulanadi.
- ha —
display: nonebilan. - ha — prerender: fonda, eng past ustuvorlikda chiziladi, lekin effektlarsiz.
2-mashq (o'rta): savat soni yo'qolmasin
Ikki tab: «Menyu» (ichida «+1» tugmasi va "Savatda: N") va «Manzil». Tab almashganda savat soni 0 ga tushyapti. <Activity> bilan tuzating — Cart komponentining kodiga tegmang. Ishora: «State saqlanadi» bo'limi.
import { useState } from "react";
function Cart() {
const [count, setCount] = useState(0);
return (
<div>
<p>Savatda: {count}</p>
<button onClick={() => setCount(count + 1)}>+1</button>
</div>
);
}
export default function App() {
const [tab, setTab] = useState("menu");
return (
<div>
<button onClick={() => setTab("menu")}>Menyu</button>{" "}
<button onClick={() => setTab("address")}>Manzil</button>
{tab === "menu" && <Cart />}
{tab === "address" && <p>Chilonzor, 9-kvartal</p>}
</div>
);
}Ekranda:
Menyu Manzil
Savatda: 0
+1Yechim
import { Activity, useState } from "react";
function Cart() {
const [count, setCount] = useState(0);
return (
<div>
<p>Savatda: {count}</p>
<button onClick={() => setCount(count + 1)}>+1</button>
</div>
);
}
export default function App() {
const [tab, setTab] = useState("menu");
return (
<div>
<button onClick={() => setTab("menu")}>Menyu</button>{" "}
<button onClick={() => setTab("address")}>Manzil</button>
<Activity mode={tab === "menu" ? "visible" : "hidden"}>
<Cart />
</Activity>
{tab === "address" && <p>Chilonzor, 9-kvartal</p>}
</div>
);
}Ekranda:
Menyu Manzil
Savatda: 2
+1«Manzil» tabida Cart yashirindi, lekin daraxtdan chiqmadi — count 2 saqlandi. Manzil esa oddiy shartli chizishda qoldi: unda state yo'q, saqlashning foydasi ham yo'q.
3-mashq (qiyin): taymer yashirinda to'xtasin
«Buyurtma holati» tabi har 100 ms da serverdan holatni "so'raydi" (setInterval). Hozir tab CSS hidden bilan yashiriladi — yashirin paytda ham so'rayveradi. <Activity> ga o'tkazing: yashirin paytda so'rov to'xtasin, qaytganda — davom etsin. Qaytganda konsolga yashirin paytdagi so'rovlar soni chiqsin — u 0 bo'lishi kerak.
Sinov: tab ochiq (250 ms) → yopiladi (400 ms) → ochiladi (250 ms). Ishora: «Effektlar to'xtaydi» bo'limi; interval cleanup'da clearInterval.
function OrderStatus() {
useEffect(() => {
const id = setInterval(() => console.log("so'rov"), 100);
return () => clearInterval(id);
}, []);
return <p>Buyurtma: tayyorlanmoqda</p>;
}
// App: <div hidden={tab !== "status"}><OrderStatus /></div>Yechim
import { Activity, useEffect, useState } from "react";
let requests = 0; // "serverga" ketgan so'rovlar
let stoppedAt = null; // to'xtagan paytdagi soni
function OrderStatus() {
useEffect(() => {
if (stoppedAt === null) {
console.log("kuzatuv: boshlandi");
} else {
const extra = requests - stoppedAt;
console.log(`kuzatuv: qaytdi, yashirinda ${extra} ta so'rov`);
}
const id = setInterval(() => requests++, 100);
return () => {
clearInterval(id);
stoppedAt = requests;
console.log("kuzatuv: to'xtadi");
};
}, []);
return <p>Buyurtma: tayyorlanmoqda</p>;
}
export default function App() {
const [tab, setTab] = useState("status");
return (
<div>
<button onClick={() => setTab("status")}>Holat</button>{" "}
<button onClick={() => setTab("menu")}>Menyu</button>
<Activity mode={tab === "status" ? "visible" : "hidden"}>
<OrderStatus />
</Activity>
{tab === "menu" && <p>Osh, lag'mon</p>}
</div>
);
}Konsolda:
kuzatuv: boshlandi
kuzatuv: to'xtadi
kuzatuv: qaytdi, yashirinda 0 ta so'rovEkranda:
Holat Menyu
Buyurtma: tayyorlanmoqda«Menyu» ochiq bo'lgan ~400 ms davomida bitta ham so'rov yo'q — effekt cleanup'i intervalni to'xtatdi. So'rovlar sonini to'g'ridan-to'g'ri chiqarmadik: u vaqtga bog'liq. Farq esa — aniq 0. «Holat» ga qaytganda effekt qayta ulandi. OrderStatus kodi o'zgarmadi: to'g'ri yozilgan cleanup Activity bilan o'z-o'zidan ishladi. CSS hidden bilan esa 400 ms da yana 4 ta "so'rov" bo'lardi.
4-mashq: Vazifalar qadami
feat/statistika-activity branch'ida BatafsilStatistika ga «Teglar tartibi» tanlovini, StatistikaPaneli ga ochilgan va <Activity> ni qo'shing. Vitest: tanlov alifboga o'tkazilib, panel yopilib-ochilganda saqlanadi. Commit qiling va PR oching.
Yechim
Tekshiruv ro'yxati:
npm run preview→ DevTools → Network: sahifa ochilganda statistika chunk'i yuklanmaydi (Activity hali yo'q). Buochilgansiz qilinsa, chunk darhol yuklanardi — tekshirib ko'ring va qaytaring.- Panelni oching, «Alifbo bo'yicha» ni tanlang, yoping, oching — tanlov joyida. Elements'da yopiq panel —
style="display: none !important;". - DevTools → Console: CSP ogohlantirishi yo'q.
npm test— Vitest 38. Commit —feat: statistika paneli <Activity> bilan — yopilganda holat saqlanadi.
10. Real ishda
- Tablar, yon panellar, "orqaga" navigatsiya — Activity'ning asosiy uyi. Ro'yxat → tafsilot → orqaga: ro'yxatning scroll va filtrlari joyida.
- Framework'lar — Next.js va React Router ichki navigatsiyada Activity'dan foydalanib, oldingi sahifani saqlashi va keyingisini oldindan chizishi mumkin (Next.js performance).
- Mobil tajriba — native ilovalardagi "tab bar" xulqi (har tab o'z holatida) — web'da endi oddiy React bilan.
- Intervyu savollari: "
<Activity>va shartli chizish farqi?", "yashirin Activity'da effektlar bilan nima bo'ladi?", "prerender nima va qachon zararli?".
Xulosa
<Activity mode="hidden">— DOM va state saqlanadi, effektlar to'xtaydi (cleanup),display: none.visiblega qaytganda — darhol, effektlar qayta ulanadi; to'g'ri cleanup — shart.- Boshidan
hidden— fonda, past ustuvorlikda prerender (effektlarsiz); Suspense/lazy yuklanishni ham boshlaydi. - Prerender — ehtimoliy keyingi ekran uchun; og'ir va kamdan-kam narsa — birinchi ochilishdan keyin.
- Media (
<video>) va effektdan tashqaridagi taymerlar o'zi to'xtamaydi. vazifalar: statistika paneli —ochilgan && <Activity>; tanlov saqlanadi, chunk sahifa ochilishida yuklanmaydi.
Keyingi dars: Hujjat metadata va resurs API'lari — <title>, <meta>, <link> ni komponent ichida yozish va resurslarni oldindan yuklash.
Manbalar
- React:
<Activity>— react.dev/reference/react/Activity (2026-10 holati, React 19.3) - React blog: "React 19.2" (2025-10-01) —
<Activity>— react.dev/blog/2025/10/01/react-19-2 - React: "Preserving and Resetting State" — react.dev/learn/preserving-and-resetting-state
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!