Mundarija (30)
- Bu darsda
- 1. Nega bu kerak?
- 2. React 19.3.0 da bormi — tekshiramiz
- 3. Birinchi <ViewTransition>
- 3.1 Karta paydo bo'ladi
- 3.2 Nima bo'ldi
- 3.3 Faqat Transition'da
- 4. To'rt faollashish: enter, exit, update, share
- 4.1 Qachon nima
- 4.2 Kirish va chiqish o'z animatsiyasi bilan
- 4.3 Nomlar: React o'zi beradi
- 4.4 Ro'yxat tartibi — update
- 5. name va share: element boshqa joyga uchadi
- 6. addTransitionType: yo'nalish
- 6.1 Hodisalar: onEnter, onExit, onUpdate, onShare
- 7. Router integratsiyasi
- 7.1 React Router 8 navigatsiyani o'zi startTransition ga o'raydi
- 7.2 O'lchov: bitta, keyin uchta o'tish
- 7.3 Sahifa almashsa — update, enter emas
- 8. Harakatni kamaytirish va CSP
- 9. Kanon nega <ViewTransition> ni olmadi — tajriba
- 10. Ko'p uchraydigan xatolar
- 11. Mashqlar
- 1-mashq (oson): o'tish bo'ladimi?
- 2-mashq (o'rta): filtr animatsiyasiz
- 3-mashq (qiyin): bron qadamlari — yo'nalish bilan
- 4-mashq: Vazifalar qadami — tajriba (commit yo'q)
- 12. Real ishda
- Xulosa
- Manbalar
React'da View Transitions: <ViewTransition>, addTransitionType va router integratsiyasi
Qisqacha:
<ViewTransition>— React 19.3.0 da barqaror komponent. U ichidagi elementga brauzerning View Transitions API'sini ulaydi: React o'zidocument.startViewTransitionni chaqiradi, nom beradi va kerakli paytda DOM'ni yangilaydi. U faqat Transition ichidagi yangilanishda ishlaydi:startTransition,useDeferredValue, Action yoki Suspense. OddiysetState— animatsiyasiz.enter,exit,update,share— qaysi holatda qanday animatsiya,addTransitionType— yo'nalish. React Router 8 navigatsiyani o'zistartTransitionga o'raydi. Shuning uchun router'ningviewTransitionprop'i bilan birga ishlatilsa, ikkita o'tish to'qnashadi — Chrome'da o'lchadik.
Bu darsda
<ViewTransition>brauzer API'si ustida nima qilishini va nega faqat Transition'da ishlashini tushuntirasiz.enter,exit,update,sharevanamebilan kirish, chiqish, ro'yxat tartibi va "uchuvchi" elementni yasaysiz.addTransitionTypebilan "oldinga" va "orqaga" o'tishlarni farqlaysiz.- React Router bilan ulaysiz va ikki mexanizm to'qnashuvidan qochasiz.
- Kanon nega
<ViewTransition>ni olmaganini o'lchov bilan bilasiz.
Oldin bilishingiz kerak: View Transitions: sahifa va holatlar orasida silliq o'tish, Concurrent rendering va useTransition, Scroll, breadcrumb va sahifa o'tishlari, Motion IV.
1. Nega bu kerak?
View Transitions darsida brauzerning o'zi chizadigan o'tishni ko'rdik. document.startViewTransition(yangila) — brauzer eski holatni suratga oladi, yangila() DOM'ni o'zgartiradi, keyin ikki surat orasida animatsiya. Kutubxona yo'q, 0 KB JavaScript.
React'da bu qiyin. yangila() ichida DOM'ni darhol o'zgartirish kerak. React esa DOM'ni o'zi xohlagan paytda yangilaydi: setState dan keyin, navbat bilan. Qo'lda yozilsa, flushSync bilan React'ni "majburlash" kerak. Bu Concurrent rendering darsidagi barcha yutuqni bekor qiladi. 19-qismda router'ning viewTransition prop'i buni sahifalar uchun hal qilgan edi. Lekin sahifa ichidagi kartalar, ro'yxatlar-chi?
React 19.3 javobi — <ViewTransition> komponenti. React startViewTransition ni o'zi, o'zining commit paytida chaqiradi. Siz faqat "mana bu qism o'tishda qatnashsin" deysiz.
Hayotiy o'xshatish: fotograf. CSS darsida suratni o'zingiz olardingiz: "hamma joyida turing — chiq-chiq — endi o'zgaring — chiq-chiq". <ViewTransition> da fotograf React. U tayyor bo'lganini o'zi biladi.
Bu darsning holati boshqacha. Xaritada <ViewTransition> "eksperimental" deb yozilgan, lekin React 19.3.0 da u barqaror eksport. vazifalar kanoni uni ishlatmadi (20-qaror 7). Shuning uchun "Vazifalar qadami" o'rnida — Chrome'dagi o'lchov.
2. React 19.3.0 da bormi — tekshiramiz
Avval faktni tekshiramiz: react paketi nimani eksport qiladi? Natija oynasidagi React — 19.3.0:
import * as React from "react";
console.log("versiya:", React.version);
console.log("ViewTransition:", typeof React.ViewTransition);
console.log("addTransitionType:", typeof React.addTransitionType);
console.log(
"unstable_ViewTransition:",
"unstable_ViewTransition" in React,
);
export default function App() {
return null;
}Konsolda:
versiya: 19.3.0
ViewTransition: symbol
addTransitionType: function
unstable_ViewTransition: falseEkranda:
(bo'sh)ViewTransition — symbol: Fragment, Suspense, Activity kabi maxsus React turi, oddiy funksiya emas. unstable_ prefiksi yo'q — barqaror API. @types/react 19.3.0 da ham ViewTransitionProps bor va komponent @version 19.3.0 bilan belgilangan. Eski maqolalarda unstable_ViewTransition va "faqat canary/experimental" degan gaplarni ko'rasiz — ular 19.3 dan oldingi davr uchun.
3. Birinchi <ViewTransition>
3.1 Karta paydo bo'ladi
Osh kartasi: «Tarkibi» bosilsa, tarkib qatori ochiladi. Ochilish startTransition ichida:
import { ViewTransition, startTransition, useState } from "react";
const css = `
::view-transition-group(*) { animation-duration: 0.4s; }
@media (prefers-reduced-motion: reduce) {
::view-transition-group(*), ::view-transition-old(*),
::view-transition-new(*) { animation: none; }
}
`;
export default function App() {
const [open, setOpen] = useState(false);
function toggle() {
startTransition(() => setOpen((o) => !o));
}
return (
<div>
<style>{css}</style>
<button onClick={toggle}>Tarkibi</button>
{open && (
<ViewTransition>
<p>Guruch, sabzi, go'sht, zira</p>
</ViewTransition>
)}
<p>Osh — 35 000 so'm</p>
</div>
);
}Ekranda:
Tarkibi
Guruch, sabzi, go'sht, zira
Osh — 35 000 so'm<style> ichidagi CSS ekranga chiqmaydi — u faqat o'tish pseudo-elementlarini sozlaydi.
3.2 Nima bo'ldi
«Ishga tushir» dan keyin «Tarkibi» ni bir necha marta bosing: tarkib qatori yumshoq paydo bo'ladi va so'nadi. Narx qatori esa pastga sirpanadi, sakramaydi. CSS'da biz faqat davomiylikni yozdik. Qolganini React va brauzer qildi:
sequenceDiagram
participant S as startTransition
participant R as React
participant B as Brauzer
S->>R: setOpen(true) — Transition
R->>R: render: yangi daraxt tayyor
R->>B: startViewTransition, nomlar qo'yildi
B->>B: eski surat
B->>R: DOM'ni yangila
R->>B: commit: tarkib qo'shildi
B->>B: yangi surat, animatsiyaAsosiy farq — uchinchi qadam. React avval yangi holatni xotirada tayyorlaydi (render). DOM'ga yozishdan (commit) oldin brauzerga "suratga ol" deydi. Shunda flushSync kerak bo'lmaydi.
Tekshiruvchi (jsdom) bu yerda faqat yakuniy matnni ko'radi: unda document.startViewTransition yo'q. Bunday brauzerda React o'tishsiz, oddiy commit qiladi — xato yo'q. Bu progressive enhancement: API bo'lmasa, ilova o'tishsiz ishlayveradi.
3.3 Faqat Transition'da
Endi xuddi shu kod, faqat startTransition siz:
export default function App() {
const [open, setOpen] = useState(false);
return (
<div>
<style>{css}</style>
<button onClick={() => setOpen((o) => !o)}>Tarkibi</button>
{open && (
<ViewTransition>
<p>Guruch, sabzi, go'sht, zira</p>
</ViewTransition>
)}
<p>Osh — 35 000 so'm</p>
</div>
);
}Ekranda:
Tarkibi
Guruch, sabzi, go'sht, zira
Osh — 35 000 so'mEkran o'sha, lekin brauzerda bosib ko'ring — animatsiya yo'q, tarkib sakrab chiqadi. Biz Chrome 155 da document.startViewTransition ni "kuzatib" o'lchadik (alohida tajriba sahifasi, React 19.3.0, Vite build):
oddiy: VT chaqiruvlari jami 0
oddiy: VT chaqiruvlari jami 0
otish: VT chaqiruvlari jami 1
otish: VT chaqiruvlari jami 2Ikki marta oddiy setState — 0 ta o'tish. Ikki marta startTransition — har biriga bitta.
Nega shunday qaror? Oddiy (shoshilinch) yangilanish — klaviatura, bosish javobi. React uni darhol ko'rsatishga va'da beradi. View Transition esa bir necha o'n millisekund kutadi: avval surat, keyin DOM. @types/react izohida aynan shunday yozilgan. Sinxron yangilanish — o'tishdan "chiqish yo'li": u darhol commit bo'lishini kafolatlaydi, View Transition esa buni qila olmaydi.
Qaysi yangilanishlar o'tish yasaydi:
| Yangilanish | O'tish |
|---|---|
onClick dagi setState |
yo'q |
startTransition(() => setState(…)) |
bor |
useDeferredValue ning kechikkan qiymati |
bor |
Action (<form action>, useActionState) |
bor |
| Suspense: fallback → kontent | bor |
flushSync |
yo'q |
Tekshirib ko'ring: Qidiruv maydoni: har harfda
setQuery(…), ro'yxat esauseDeferredValue(query)bilan filtrlanadi va har qator<ViewTransition key={id}>ichida. Harf terilganda maydon "qotib" qoladimi?
Javob
Yo'q. Maydondagi matn — oddiy shoshilinch yangilanish, u darhol chiziladi va o'tishsiz. Ro'yxat esa kechiktirilgan qiymat bilan, ya'ni Transition sifatida chiziladi — o'sha qism View Transition bilan animatsiya bo'ladi. React ikki yangilanishni ajratadi: tez javob kerak bo'lgani tez, "chiroyli" bo'lishi mumkin bo'lgani — o'tish bilan (useDeferredValue darsidagi g'oya).
4. To'rt faollashish: enter, exit, update, share
4.1 Qachon nima
<ViewTransition> o'z holatiga qarab to'rt xil "faollashadi":
| Holat | Qachon |
|---|---|
| enter | <ViewTransition> (yoki uning ota komponenti) Transition'da qo'shildi |
| exit | Transition'da o'chirildi |
| update | ichidagi DOM o'zgardi yoki o'lchami o'zgardi |
| share | bir xil name li biri o'chdi, boshqasi paydo bo'ldi |
Har holat uchun prop'ga o'tish classi beriladi: <ViewTransition enter="kirish" exit="chiqish">. React uni elementning view-transition-class iga yozadi (CSS darsidagi view-transition-class ning o'zi). "none" — shu holatda o'tishni o'chirish. default — boshqa hamma holatlar uchun.
4.2 Kirish va chiqish o'z animatsiyasi bilan
import { ViewTransition, startTransition, useState } from "react";
const css = `
@keyframes tushish { from { opacity: 0; translate: 0 -12px; } }
@keyframes ketish { to { opacity: 0; translate: 16px 0; } }
::view-transition-new(.kirish) { animation: tushish 0.3s ease-out; }
::view-transition-old(.chiqish) { animation: ketish 0.2s ease-in; }
@media (prefers-reduced-motion: reduce) {
::view-transition-group(*), ::view-transition-old(*),
::view-transition-new(*) { animation: none; }
}
`;
export default function App() {
const [open, setOpen] = useState(false);
return (
<div>
<style>{css}</style>
<button onClick={() => startTransition(() => setOpen(!open))}>
Tarkibi
</button>
{open && (
<ViewTransition enter="kirish" exit="chiqish">
<p>Guruch, sabzi, go'sht, zira</p>
</ViewTransition>
)}
</div>
);
}Ekranda:
Tarkibi
Guruch, sabzi, go'sht, ziraCSS'ni o'qiymiz:
::view-transition-new(.kirish)— "kirish" class'idagi elementlarning yangi surati. Paydo bo'layotgan element faqat yangi suratga ega — u yuqoridan tushadi.::view-transition-old(.chiqish)— chiqayotganning eski surati, o'ngga siljib so'nadi.- Davomiylik har biriga alohida. UI animatsiya tamoyillari darsidagi qoida: chiqish kirishdan qisqaroq.
Chrome'da o'lchadik: kartani yopishda React elementga view-transition-class: chiqish qo'ydi (P:_t_3_:chiqish — teg, nom, class).
4.3 Nomlar: React o'zi beradi
View Transition'da har ishtirokchiga noyob nom kerak. CSS darsida nomni qo'lda yozganmiz (view-transition-name: osh-karta). <ViewTransition> da name bermasangiz, React o'zi beradi. Chrome'da yozib olingan nomlar: _t_0_, _t_1_, _t_2_ — uchta ro'yxat qatori, _t_3_ — karta. Nom faqat o'tish paytida qo'yiladi va keyin olib tashlanadi. Shuning uchun "takroriy nom" xatosi (CSS darsidagi eng ko'p uchraydigan xato) o'z-o'zidan yo'qoladi.
4.4 Ro'yxat tartibi — update
Har qatorni <ViewTransition key> ga o'rasak, tartib o'zgarganda har qator o'z yangi joyiga siljiydi:
import { ViewTransition, startTransition, useState } from "react";
const MENU = [
{ name: "Osh", price: 35000 },
{ name: "Lag'mon", price: 28000 },
{ name: "Manti", price: 30000 },
];
export default function App() {
const [list, setList] = useState(MENU);
function sortCheap() {
startTransition(() => {
setList([...list].sort((a, b) => a.price - b.price));
});
}
return (
<div>
<button onClick={sortCheap}>Arzonidan</button>
<ul>
{list.map((d) => (
<ViewTransition key={d.name}>
<li>
{d.name} — {d.price}
</li>
</ViewTransition>
))}
</ul>
</div>
);
}Ekranda:
Arzonidan
Lag'mon — 28000
Manti — 30000
Osh — 35000Natija oynasida bosing: osh pastga siljiydi, lag'mon va manti yuqoriga. Bu Motion III dagi layout ning ishi edi — endi kutubxonasiz. Brauzer har qatorning eski va yangi joyini suratdan biladi.
key <ViewTransition> ning o'zida. U ro'yxatning to'g'ridan-to'g'ri bolasi, React qatorlarni u orqali taniydi.
5. name va share: element boshqa joyga uchadi
Ikki turli <ViewTransition> bir xil name olsa, biri o'chib ikkinchisi paydo bo'lganda brauzer ularni bitta element deb biladi. Ular orasida o'rin va o'lcham animatsiyasi bo'ladi. Motion'dagi layoutId ning (Motion III) View Transitions'dagi egizagi:
import { ViewTransition, startTransition, useState } from "react";
const small = { width: 80, padding: 8, border: "2px solid #1d4ed8" };
const big = { width: 260, padding: 24, border: "2px solid #1d4ed8" };
export default function App() {
const [open, setOpen] = useState(false);
const toggle = () => startTransition(() => setOpen(!open));
return open ? (
<ViewTransition name="osh-rasm" share="uchish">
<button style={big} onClick={toggle}>
Osh — 35 000 so'm (yopish)
</button>
</ViewTransition>
) : (
<ViewTransition name="osh-rasm" share="uchish">
<button style={small} onClick={toggle}>
Osh
</button>
</ViewTransition>
);
}Ekranda:
Osh — 35 000 so'm (yopish)Galereyadagi kichik rasm → katta ko'rinish, ro'yxatdagi karta → batafsil sahifa — shu naqsh. Ikki shart bor. name sahifada bir vaqtda faqat bitta ko'rinadigan <ViewTransition> da bo'lsin. Va ikkalasi bitta Transition'da almashsin. Chrome o'lchovida taom-rasm nomli umumiy guruh shunday chiqdi: ::view-transition-group(taom-rasm).
6. addTransitionType: yo'nalish
Slayderda «Keyingi» — yangi taom o'ngdan kirsin, «Oldingi» — chapdan. Animatsiya sababga bog'liq. addTransitionType("oldinga") — Transition ichida chaqiriladi va o'tishga yorliq qo'yadi. Prop'larga obyekt beriladi: tur → class.
import {
ViewTransition,
addTransitionType,
startTransition,
useState,
} from "react";
const DISHES = ["Osh", "Lag'mon", "Manti"];
const css = `
@keyframes ongdan { from { translate: 40px 0; opacity: 0; } }
@keyframes chapdan { from { translate: -40px 0; opacity: 0; } }
::view-transition-new(.ongdan) { animation: ongdan 0.3s; }
::view-transition-new(.chapdan) { animation: chapdan 0.3s; }
`;
export default function App() {
const [i, setI] = useState(0);
function go(step, type) {
startTransition(() => {
addTransitionType(type);
setI((i + step + DISHES.length) % DISHES.length);
});
}
return (
<div>
<style>{css}</style>
<button onClick={() => go(-1, "orqaga")}>Oldingi</button>{" "}
<button onClick={() => go(1, "oldinga")}>Keyingi</button>
<ViewTransition
key={DISHES[i]}
enter={{ oldinga: "ongdan", orqaga: "chapdan" }}
exit="none"
>
<h2>{DISHES[i]}</h2>
</ViewTransition>
</div>
);
}Ekranda:
Oldingi Keyingi
Lag'monkey={DISHES[i]} — har taom "yangi" komponent, demak har almashinuvda enter va exit. enter={{ oldinga: "ongdan", orqaga: "chapdan" }} — tur bo'yicha class. exit="none" — chiqayotgan taom alohida animatsiya qilmasin (u ildiz crossfade'ida so'nadi).
Chrome'da yozib olindi: addTransitionType("oldinga") dan keyin brauzerning ViewTransition obyektida types: ["oldinga"], onEnter esa ikkinchi argumentda [oldinga] oldi. Ya'ni React turlarni brauzerga uzatadi. CSS darsidagi :active-view-transition-type(oldinga) CSS selektori ham ishlaydi.
6.1 Hodisalar: onEnter, onExit, onUpdate, onShare
Har holatga hodisa ham bor: onEnter={(instance, types) => …}. instance.name — o'tish nomi (_t_4_ yoki siz bergan). Funksiya qaytarilsa — tozalash. Bu hodisalar faqat haqiqiy o'tishda chaqiriladi: API yo'q brauzerda (va tekshiruvchimizdagi jsdom'da) ular jim. Shuning uchun muhim mantiqni (ma'lumot saqlash, fokus) ularga bog'lamang.
7. Router integratsiyasi
7.1 React Router 8 navigatsiyani o'zi startTransition ga o'raydi
19/#10 da <NavLink viewTransition> ni ko'rdik: router o'zi document.startViewTransition ni chaqiradi. Endi React'ning <ViewTransition> i ham bor. Ikkalasi birga nima qiladi?
React Router 8.4.0 manba kodida (RouterProvider) — useTransitions sozlamasi. Hujjat izohi: "undefined qoldirilsa, router holatining hamma yangilanishlari React.startTransition ga o'raladi". Demak <ViewTransition> sahifa almashganda o'z-o'zidan ishlaydi — viewTransition prop'isiz ham.
7.2 O'lchov: bitta, keyin uchta o'tish
Tajriba: createMemoryRouter + RouterProvider ("react-router" dan, vazifalar dagidek), ikki sahifa, har biri <ViewTransition> ichida. Avval oddiy navigatsiya, keyin viewTransition: true bilan (Chrome 155):
navigate (oddiy): VT 1 Statistika
navigate (viewTransition: true): VT 3 Ro'yxat
{"tur":[],"psevdo":[],"ms":345,"xato":"AbortError: Transition was skipped. New ViewTransition started"}- Oddiy navigatsiya — bitta o'tish. React'niki, chunki router
startTransitionishlatdi. viewTransition: true— yana ikkita: avval routerstartViewTransitionni chaqirdi. Ichida ReactstartTransitionni ko'rib, o'zinikini boshladi. Brauzer bir vaqtda bitta o'tishga ruxsat beradi — birinchisi bekor bo'ldi:AbortError: Transition was skipped. New ViewTransition started. Tarjimasi: "o'tish o'tkazib yuborildi — yangi ViewTransition boshlandi".
Sahifa to'g'ri ochildi, konsolda ushlanmagan xato yo'q — router xatoni o'zi ushladi. Lekin bekorga bajarilgan ish va kutilmagan animatsiya bor. Qoida: bitta mexanizm tanlang. <ViewTransition> ishlatsangiz — viewTransition prop'ini olib tashlang.
7.3 Sahifa almashsa — update, enter emas
O'sha o'lchovdagi hodisalar logi:
"log":["update Statistika","update Ro'yxat"]Sahifa almashdi, lekin enter/exit emas — update. Sababi React'ning moslashtirish qoidasi (State'ning saqlanishi va key): ikkala sahifa bir xil komponent, bir xil joyda. React uni "yangilandi" deb biladi va eski hamda yangi sahifa crossfade bo'ladi. Kirish/chiqish animatsiyasi kerak bo'lsa — key:
const { pathname } = useLocation();
return (
<ViewTransition key={pathname} enter="kirish" exit="chiqish">
<Outlet />
</ViewTransition>
);key bilan qayta o'lchadik — log: ["exit Ro'yxat","enter Statistika","exit Statistika","enter Ro'yxat"]. Endi har sahifa chiqadi va kiradi.
Next.js App Router ham shu komponent bilan ishlaydi. Uning hujjatida: React 19.3 bilan "sozlamasiz" — avvalgi experimental.viewTransition bayrog'i olib tashlangan. Eski maqolalarda shu bayroqni ko'rasiz. Next.js'ni keyingi qismlarda o'rganamiz — hozir bilish shart emas.
8. Harakatni kamaytirish va CSP
Harakatni kamaytirish. React prefers-reduced-motion ga qaramaydi — o'tish baribir yaratiladi. Animatsiyani CSS o'chiradi: yuqoridagi bloklardagi @media (prefers-reduced-motion: reduce) qoidasi. O'lchov (Chrome, prefers-reduced-motion: reduce emulyatsiyasi, kanon CSS'i): o'tish davomiyligi ~320–350 ms dan 19–27 ms ga tushdi — surat olish va almashtirish qoldi, harakat yo'q. Bu qoida vazifalar ning asos.css ida 19-qismdan beri bor.
CSP. vazifalar CSP'si (style-src 'self', Trusted Types) ostida 5 xil o'tish — 0 buzilish. React nomni element.style.viewTransitionName = … bilan qo'yadi (CSSOM — ruxsat). <style> tegi yaratmaydi. Motion III dagi popLayout va Radix modal rejimidan farqli — qattiq CSP bilan to'liq chiqishadi.
Brauzer mosligi. View Transitions darsidagi jadval: bir sahifa ichidagi o'tishlar — Baseline 2025-yil oktabrdan (Firefox 144 oxirgi bo'lib qo'shgan). Eski brauzerda — o'tishsiz, xatosiz.
9. Kanon nega <ViewTransition> ni olmadi — tajriba
vazifalar da ikki joyda harakat bor: sahifa almashishi va ro'yxat qatorlari. Ikkalasi <ViewTransition> ga mos keladi. Kanon qarori (20-qaror 7, QADAMLAR asosiy qaror 7): "Kanonga kirmadi: sahifa o'tishi — router viewTransition (19/#10, ishlaydi), qator animatsiyasi — Motion; ikkinchi mexanizm qo'shilmadi."
Bugungi o'lchov bu qarorni yana bir sabab bilan mustahkamlaydi:
- Sahifa o'tishi.
vazifalardaNavLink viewTransitionbor.<ViewTransition>qo'shilsa — «Router integratsiyasi» bo'limidagi to'qnashuv. Biri olib tashlanishi kerak. Ikkalasining natijasi ko'zga bir xil (crossfade, 120 ms). - Qator animatsiyasi. Yangi qator
startTransitionsiz qo'shiladi (forma — shoshilinch yangilanish).<ViewTransition>u yerda ishlamasdi. Uni Transition'ga o'tkazish — kiritish javobini kechiktirish. - O'tish paytida bosish. 19/#10 dagi e2e topilmasi: o'tish paytida sahifa "surat", bosish unga yetmaydi. Ro'yxatda tez-tez bosiladigan tugmalar bor. Motion animatsiyasi esa haqiqiy DOM'da — bosish ishlaydi.
Qachon <ViewTransition> to'g'ri tanlov? Yangi loyihada, Motion hali yo'q bo'lsa. O'tishlar asosan navigatsiya, galereya va katalogda bo'lsa. Qattiq CSP kerak bo'lsa. 0 KB JavaScript — eng katta afzalligi.
10. Ko'p uchraydigan xatolar
| Belgi | Sabab | Davosi |
|---|---|---|
| hech qanday animatsiya yo'q | yangilanish startTransition siz |
startTransition / useDeferredValue |
konsolda AbortError: Transition was skipped |
router viewTransition + <ViewTransition> |
bitta mexanizm |
sahifa almashganda enter ishlamaydi |
bir xil komponent → update |
key={pathname} |
| ro'yxat qatorlari siljimaydi, hammasi crossfade | <ViewTransition> ro'yxatni butunlay o'raydi |
har qator alohida, key bilan |
name li element "uchmaydi" |
ikkalasi bir vaqtda ko'rinadi yoki turli Transition'da | bir Transition'da almashsin |
onEnter testda chaqirilmaydi |
jsdom'da API yo'q | mantiqni hodisaga bog'lamang |
eski kodda unstable_ViewTransition |
19.3 dan oldingi API | import { ViewTransition } from "react" |
11. Mashqlar
Mashqlar kurs/mashqlar/20/27-view-transition/ da.
1-mashq (oson): o'tish bo'ladimi?
Har yangilanish <ViewTransition> ichidagi elementni o'zgartiradi. O'tish bo'ladimi? (ha yoki yo'q)
onClick={() => setOpen(true)}→onClick={() => startTransition(() => setOpen(true))}→<form action={saveAction}>dagi Action ichida state o'zgardi →flushSync(() => setOpen(true))→
Yechim
yo'q— oddiy shoshilinch yangilanish, React uni darhol ko'rsatadi.ha— Transition.ha— Action'lar Transition ichida ishlaydi (Actions).yo'q—flushSyncmajburan sinxron commit qiladi, surat olishni kutolmaydi.
2-mashq (o'rta): filtr animatsiyasiz
«Bahor» menyusida «Faqat 30 000 gacha» katakchasi bor. Dizayner filtrlashda qolgan qatorlar silliq siljishini xohlaydi. Hozir hech narsa siljimaydi. Ikki xato bor — toping va tuzating. Natija ekrani o'zgarmasin.
Ishora: «Faqat Transition'da» va «Ro'yxat tartibi — update» bo'limlari.
import { ViewTransition, useState } from "react";
const MENU = [
{ name: "Osh", price: 35000 },
{ name: "Lag'mon", price: 28000 },
{ name: "Manti", price: 30000 },
];
export default function App() {
const [cheap, setCheap] = useState(false);
const list = cheap ? MENU.filter((d) => d.price <= 30000) : MENU;
return (
<div>
<button onClick={() => setCheap(!cheap)}>
Faqat 30 000 gacha
</button>
<ViewTransition>
<ul>
{list.map((d) => (
<li key={d.name}>{d.name}</li>
))}
</ul>
</ViewTransition>
</div>
);
}Ekranda:
Faqat 30 000 gacha
Lag'mon
MantiYechim
import { ViewTransition, startTransition, useState } from "react";
const MENU = [
{ name: "Osh", price: 35000 },
{ name: "Lag'mon", price: 28000 },
{ name: "Manti", price: 30000 },
];
export default function App() {
const [cheap, setCheap] = useState(false);
const list = cheap ? MENU.filter((d) => d.price <= 30000) : MENU;
function toggle() {
startTransition(() => setCheap(!cheap));
}
return (
<div>
<button onClick={toggle}>Faqat 30 000 gacha</button>
<ul>
{list.map((d) => (
<ViewTransition key={d.name}>
<li>{d.name}</li>
</ViewTransition>
))}
</ul>
</div>
);
}Ekranda:
Faqat 30 000 gacha
Lag'mon
MantiBirinchi xato — oddiy setCheap: Transition yo'q, o'tish yo'q. Ikkinchisi — bitta <ViewTransition> butun <ul> ni o'radi. Butun ro'yxat bitta "surat" bo'ldi va qatorlar alohida siljiy olmaydi. Har qatorga o'z <ViewTransition key> — endi osh chiqadi (exit), lag'mon va manti yangi joyiga siljiydi (update).
3-mashq (qiyin): bron qadamlari — yo'nalish bilan
Bron formasi uch qadamli: «Sana», «Odamlar», «Tasdiq». «Keyingi» — yangi qadam o'ngdan kirsin, «Orqaga» — chapdan. Talablar:
- Qadam nomi
<h2>da,<ViewTransition key={…}>ichida. - Tugmalar
startTransition+addTransitionType("oldinga" | "orqaga"). - Birinchi qadamda «Orqaga», oxirgisida «Keyingi» —
disabled. - Har o'tishda konsolga:
oldinga: Odamlarkabi.
Ishora: «addTransitionType: yo'nalish» bo'limidagi slayder. disabled tugmaning bosilishini o'chiradi.
Yechim
import {
ViewTransition,
addTransitionType,
startTransition,
useState,
} from "react";
const STEPS = ["Sana", "Odamlar", "Tasdiq"];
export default function App() {
const [step, setStep] = useState(0);
function go(delta, type) {
const next = step + delta;
startTransition(() => {
addTransitionType(type);
setStep(next);
});
console.log(`${type}: ${STEPS[next]}`);
}
return (
<div>
<ViewTransition
key={STEPS[step]}
enter={{ oldinga: "ongdan", orqaga: "chapdan" }}
exit="none"
>
<h2>{STEPS[step]}</h2>
</ViewTransition>
<button
disabled={step === 0}
onClick={() => go(-1, "orqaga")}
>
Orqaga
</button>{" "}
<button
disabled={step === STEPS.length - 1}
onClick={() => go(1, "oldinga")}
>
Keyingi
</button>
</div>
);
}Konsolda:
oldinga: Odamlar
oldinga: Tasdiq
orqaga: OdamlarEkranda:
Odamlar
Orqaga KeyingiCSS (ongdan, chapdan keyframes) — slayder misolidagidek, loyihaning CSS faylida. Haqiqiy formada qadam almashganda fokusni yangi <h2> ga o'tkazing (Fokus boshqaruvi): o'tish ko'zga ko'rinadi, Malika esa yangi qadam nomini eshitishi kerak.
4-mashq: Vazifalar qadami — tajriba (commit yo'q)
vazifalar ning alohida branch'ida (tajriba/view-transition) Qobiq.tsx dagi <Outlet /> ni <ViewTransition key={pathname}> ga o'rang va NavLink lardan viewTransition ni olib tashlang. Brauzerda bo'limlarni almashtiring, DevTools → Animations panelida o'tishni ko'ring. Keyin viewTransition ni qaytaring, <ViewTransition> ni qoldiring — konsolda nima chiqadi? Branch'ni o'chiring.
Yechim
- Faqat
<ViewTransition key={pathname}>— har bo'lim almashganda bitta o'tish: eski bo'lim chiqadi, yangisi kiradi. - Ikkalasi birga — o'tish ikki marta boshlanadi, birinchisi bekor bo'ladi (
AbortError: Transition was skipped. New ViewTransition started; router uni ushlaydi, lekin DevTools'da ikki o'tish ko'rinadi). - Xulosa — kanon qarori: bitta mexanizm.
vazifalarda routerviewTransitionqoladi. git switch main && git branch -D tajriba/view-transition.
12. Real ishda
- Katalog va galereyalar — kartadan batafsil sahifaga "uchuvchi" rasm (
name+share), filtrlashda siljiydigan kartalar. 0 KB JavaScript — onlayn do'konlar uchun muhim. - Mobil uslubdagi veb-ilovalar — ekranlar orasida "oldinga/orqaga" siljish (
addTransitionType). Telegram Mini App kabi ilovalarda (21-qism) native ilova hissini beradi. - Freymvorklar — React Router, Next.js
<ViewTransition>ni qo'llab-quvvatlashga o'tmoqda. Eski loyihalarda esa router'ning o'zviewTransitionprop'i — ikkalasini aralashtirmang. - Intervyu savollari: "
<ViewTransition>qachon ishga tushadi?", "nega oddiysetStateanimatsiya qilmaydi?", "entervaupdatefarqi?", "View Transition va Motionlayout— qachon qaysi biri?".
Xulosa
<ViewTransition>— React 19.3.0 da barqaror. ReactstartViewTransitionni o'zi, render va commit orasida chaqiradi va nomlarni o'zi beradi.- Faqat Transition'da ishlaydi:
startTransition,useDeferredValue, Action, Suspense. OddiysetState— 0 o'tish (Chrome o'lchovi). enter,exit,update,share—view-transition-classberadi;name— umumiy element;addTransitionType— yo'nalish.- React Router 8 navigatsiyani
startTransitionga o'raydi:<ViewTransition>o'zi ishlaydi.viewTransitionprop bilan birga — ikki o'tish vaAbortError. Bitta mexanizm tanlang. - CSP bilan to'liq mos (0 buzilish),
prefers-reduced-motion— CSS bilan.
Keyingi dars: GSAP: murakkab timeline va ScrollTrigger — marketing sahifalar va murakkab ketma-ketliklar uchun eng kuchli animatsiya vositasi.
Manbalar
- React:
<ViewTransition>,addTransitionType— react.dev/reference/react/ViewTransition (React 19.3.0, 2026-10);@types/react19.3.0ViewTransitionProps - React Router 8.4.0:
RouterProvideruseTransitions— reactrouter.com/explanation/react-transitions; manbareact-router/dist/production/lib/components.js - MDN: View Transition API,
ViewTransition.types— developer.mozilla.org/docs/Web/API/View_Transition_API - Next.js: View Transitions guide — nextjs.org/docs/app/guides/view-transitions ("works with no configuration", React 19.3)
- Chrome for Developers: View transition classes va types — developer.chrome.com/docs/web-platform/view-transitions
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!