Otključajte vrhunsku responzivnost korisničkog sučelja s Reactovim experimental_useTransition. Naučite kako prioritetizirati ažuriranja, spriječiti zastajkivanje i graditi besprijekorna korisnička iskustva globalno.
Ovladavanje Responzivnošću UI-ja: Dubinski Pogled na Reactov experimental_useTransition za Upravljanje Prioritetima
U dinamičnom svijetu web razvoja, korisničko iskustvo je najvažnije. Aplikacije moraju biti ne samo funkcionalne, već i nevjerojatno responzivne. Ništa ne frustrira korisnike više od sporog, zastajkujućeg sučelja koje se zamrzava tijekom složenih operacija. Moderne web aplikacije često se bore s izazovom upravljanja različitim korisničkim interakcijama uz tešku obradu podataka, renderiranje i mrežne zahtjeve, a sve to bez žrtvovanja percipiranih performansi.
React, vodeća JavaScript biblioteka za izradu korisničkih sučelja, neprestano se razvijala kako bi odgovorila na te izazove. Ključni razvoj na tom putu je uvođenje Konkurentnog Reacta (Concurrent React), skupa novih značajki koje omogućuju Reactu da istovremeno priprema više verzija korisničkog sučelja. U središtu pristupa Konkurentnog Reacta održavanju responzivnosti nalazi se koncept "Tranzicija", pokretan hookovima poput experimental_useTransition.
Ovaj sveobuhvatni vodič istražit će experimental_useTransition, objašnjavajući njegovu ključnu ulogu u upravljanju prioritetima ažuriranja, sprječavanju zamrzavanja korisničkog sučelja i, u konačnici, stvaranju fluidnog i privlačnog iskustva za korisnike diljem svijeta. Zaronit ćemo u njegovu mehaniku, praktične primjene, najbolje prakse i temeljne principe koji ga čine nezaobilaznim alatom za svakog React programera.
Razumijevanje Reactovog Konkurentnog Načina i Potrebe za Tranzicijama
Prije nego što zaronimo u experimental_useTransition, ključno je shvatiti temeljne koncepte Reactovog Konkurentnog Načina. Povijesno gledano, React je ažuriranja renderirao sinkrono. Jednom kada bi ažuriranje započelo, React se ne bi zaustavio dok se cijelo korisničko sučelje ne bi ponovno renderiralo. Iako predvidljiv, ovaj pristup mogao je dovesti do "zastajkujućeg" korisničkog iskustva, posebno kada su ažuriranja bila računalno intenzivna ili su uključivala složena stabla komponenata.
Zamislite korisnika kako tipka u polje za pretragu. Svaki pritisak tipke pokreće ažuriranje za prikaz unesene vrijednosti, ali potencijalno i operaciju filtriranja na velikom skupu podataka ili mrežni zahtjev za prijedloge pretrage. Ako je filtriranje ili mrežni zahtjev spor, korisničko sučelje bi se moglo na trenutak zamrznuti, čineći polje za unos neresponzivnim. To kašnjenje, ma koliko kratko bilo, značajno umanjuje korisnikovu percepciju kvalitete aplikacije.
Konkurentni Način mijenja ovu paradigmu. Omogućuje Reactu da radi na ažuriranjima asinkrono i, što je ključno, da prekida i pauzira rad na renderiranju. Ako stigne hitnije ažuriranje (npr. korisnik upisuje još jedan znak), React može zaustaviti svoje trenutno renderiranje, obraditi hitno ažuriranje, a zatim kasnije nastaviti prekinuti rad. Ova sposobnost prioritetiziranja i prekidanja rada je ono što dovodi do koncepta "Tranzicija".
Problem "Zastajkivanja" (Jank) i Blokirajućih Ažuriranja
"Zastajkivanje" (Jank) odnosi se na svako trzanje ili zamrzavanje korisničkog sučelja. Često se događa kada je glavna nit, odgovorna za obradu korisničkog unosa i renderiranje, blokirana dugotrajnim JavaScript zadacima. U tradicionalnom sinkronom React ažuriranju, ako renderiranje novog stanja traje 100ms, korisničko sučelje ostaje neresponzivno tijekom cijelog tog trajanja. To je problematično jer korisnici očekuju trenutnu povratnu informaciju, posebno za izravne interakcije poput tipkanja, klikanja gumba ili navigacije.
Reactov cilj s Konkurentnim Načinom i Tranzicijama je osigurati da, čak i tijekom teških računalnih zadataka, korisničko sučelje ostane responzivno na hitne korisničke interakcije. Radi se o razlikovanju između ažuriranja koja se *moraju* dogoditi sada (hitna) i ažuriranja koja *mogu* pričekati ili biti prekinuta (ne-hitna).
Uvođenje Tranzicija: Prekidiva, Ne-hitna Ažuriranja
"Tranzicija" u Reactu odnosi se na skup ažuriranja stanja koja su označena kao ne-hitna. Kada je ažuriranje omotano u tranziciju, React razumije da može odgoditi to ažuriranje ako se treba obaviti hitniji posao. Na primjer, ako pokrenete operaciju filtriranja (ne-hitna tranzicija) i odmah zatim upišete još jedan znak (hitno ažuriranje), React će dati prioritet renderiranju znaka u polju za unos, pauzirajući ili čak odbacujući ažuriranje filtriranja koje je u tijeku, a zatim ga ponovno pokrenuti kada hitni posao bude gotov.
Ovo inteligentno raspoređivanje omogućuje Reactu da održi korisničko sučelje glatkim i interaktivnim, čak i kada se u pozadini izvode zadaci. Tranzicije su ključne za postizanje istinski responzivnog korisničkog iskustva, posebno u složenim aplikacijama s bogatim interakcijama s podacima.
Dubinski Pogled na experimental_useTransition
Hook experimental_useTransition je primarni mehanizam za označavanje ažuriranja stanja kao tranzicija unutar funkcionalnih komponenata. Pruža način da se Reactu kaže: "Ovo ažuriranje nije hitno; možeš ga odgoditi ili prekinuti ako se pojavi nešto važnije."
Signatura i Povratna Vrijednost Hooka
Možete importati i koristiti experimental_useTransition u svojim funkcionalnim komponentama na ovaj način:
import { experimental_useTransition } from 'react';
function MyComponent() {
const [isPending, startTransition] = experimental_useTransition();
// ... ostatak logike vaše komponente
}
Hook vraća tuple koji sadrži dvije vrijednosti:
-
isPending(boolean): Ova vrijednost pokazuje je li tranzicija trenutno aktivna. Kada jetrue, to znači da je React u procesu renderiranja ne-hitnog ažuriranja koje je bilo omotano ustartTransition. Ovo je nevjerojatno korisno za pružanje vizualne povratne informacije korisniku, poput indikatora učitavanja ili zatamnjenog elementa sučelja, dajući mu do znanja da se nešto događa u pozadini bez blokiranja njegove interakcije. -
startTransition(function): Ovo je funkcija koju pozivate da omotate svoja ne-hitna ažuriranja stanja. Sva ažuriranja stanja izvršena unutar callbacka proslijeđenogstartTransitionbit će tretirana kao tranzicija. React će zatim ta ažuriranja rasporediti s nižim prioritetom, čineći ih prekidivima.
Uobičajeni obrazac uključuje pozivanje startTransition s callback funkcijom koja sadrži vašu logiku ažuriranja stanja:
startTransition(() => {
// Sva ažuriranja stanja unutar ovog callbacka smatraju se ne-hitnima
setSomeState(newValue);
setAnotherState(anotherValue);
});
Kako Funkcionira Upravljanje Prioritetima Tranzicija
Srž genijalnosti experimental_useTransition leži u njegovoj sposobnosti da omogući Reactovom internom raspoređivaču da učinkovito upravlja prioritetima. Razlikuje dvije glavne vrste ažuriranja:
- Hitna Ažuriranja: To su ažuriranja koja zahtijevaju trenutnu pažnju, često izravno povezana s korisničkom interakcijom. Primjeri uključuju tipkanje u polje za unos, klikanje gumba, prelazak mišem preko elementa ili odabir teksta. React daje prioritet ovim ažuriranjima kako bi osigurao da se korisničko sučelje čini trenutnim i responzivnim.
-
Ne-hitna (Tranzicijska) Ažuriranja: To su ažuriranja koja se mogu odgoditi ili prekinuti bez značajnog narušavanja neposrednog korisničkog iskustva. Primjeri uključuju filtriranje velikog popisa, učitavanje novih podataka s API-ja, složene izračune koji vode do novih stanja korisničkog sučelja ili navigaciju na novu rutu koja zahtijeva teško renderiranje. To su ažuriranja koja omotavate u
startTransition.
Kada se hitno ažuriranje dogodi dok je tranzicijsko ažuriranje u tijeku, React će:
- Pauzirati tekući rad na tranziciji.
- Odmah obraditi i renderirati hitno ažuriranje.
- Nakon što je hitno ažuriranje završeno, React će ili nastaviti pauzirani rad na tranziciji ili, ako se stanje promijenilo na način koji čini stari rad na tranziciji nevažnim, mogao bi odbaciti stari rad i započeti novu tranziciju ispočetka s najnovijim stanjem.
Ovaj mehanizam je ključan za sprječavanje zamrzavanja korisničkog sučelja. Korisnici mogu nastaviti tipkati, klikati i komunicirati, dok se složeni pozadinski procesi elegantno nadoknađuju bez blokiranja glavne niti.
Praktične Primjene i Primjeri Koda
Istražimo neke uobičajene scenarije gdje experimental_useTransition može dramatično poboljšati korisničko iskustvo.
Primjer 1: Pretraživanje/Filtriranje s Prijedlozima (Type-Ahead)
Ovo je možda najklasičniji slučaj upotrebe. Zamislite polje za pretragu koje filtrira veliki popis stavki. Bez tranzicija, svaki pritisak tipke mogao bi pokrenuti ponovno renderiranje cijelog filtriranog popisa, što dovodi do primjetnog kašnjenja unosa ako je popis opsežan ili je logika filtriranja složena.
Problem: Kašnjenje unosa pri filtriranju velikog popisa.
Rješenje: Omotajte ažuriranje stanja za filtrirane rezultate u startTransition. Ažuriranje stanja vrijednosti unosa neka ostane trenutno.
import React, { useState, experimental_useTransition } from 'react';
const ALL_ITEMS = Array.from({ length: 10000 }, (_, i) => `Stavka ${i + 1}`);
function FilterableList() {
const [inputValue, setInputValue] = useState('');
const [filteredItems, setFilteredItems] = useState(ALL_ITEMS);
const [isPending, startTransition] = experimental_useTransition();
const handleInputChange = (event) => {
const newInputValue = event.target.value;
setInputValue(newInputValue); // Hitno ažuriranje: Odmah prikaži upisani znak
// Ne-hitno ažuriranje: Započni tranziciju za filtriranje
startTransition(() => {
const lowercasedInput = newInputValue.toLowerCase();
const newFilteredItems = ALL_ITEMS.filter(item =>
item.toLowerCase().includes(lowercasedInput)
);
setFilteredItems(newFilteredItems);
});
};
return (
Primjer Pretraživanja s Prijedlozima
{isPending && Filtriranje stavki...
}
{filteredItems.map((item, index) => (
- {item}
))}
);
}
Objašnjenje: Kada korisnik tipka, setInputValue se ažurira odmah, čineći polje za unos responzivnim. Računalno teže ažuriranje setFilteredItems omotano je u startTransition. Ako korisnik upiše još jedan znak dok je filtriranje još u tijeku, React će dati prioritet novom ažuriranju setInputValue, pauzirati ili odbaciti prethodni rad na filtriranju i započeti novu tranziciju filtriranja s najnovijom vrijednošću unosa. Zastavica isPending pruža ključnu vizualnu povratnu informaciju, pokazujući da je pozadinski proces aktivan bez blokiranja glavne niti.
Primjer 2: Prebacivanje Između Tabova s Teškim Sadržajem
Razmotrite aplikaciju s više tabova, gdje svaki tab može sadržavati složene komponente ili grafikone čije renderiranje traje. Prebacivanje između ovih tabova može uzrokovati kratko zamrzavanje ako se sadržaj novog taba renderira sinkrono.
Problem: Zastajkujuće sučelje pri prebacivanju tabova koji renderiraju složene komponente.
Rješenje: Odgodite renderiranje teškog sadržaja novog taba koristeći startTransition.
import React, { useState, experimental_useTransition } from 'react';
// Simulacija teške komponente
const HeavyContent = ({ label }) => {
const startTime = performance.now();
while (performance.now() - startTime < 50) { /* Simulacija rada */ }
return Ovo je sadržaj {label}. Potrebno je neko vrijeme za renderiranje.
;
};
function TabbedInterface() {
const [activeTab, setActiveTab] = useState('tabA');
const [displayTab, setDisplayTab] = useState('tabA'); // Tab koji se stvarno prikazuje
const [isPending, startTransition] = experimental_useTransition();
const handleTabClick = (tabName) => {
setActiveTab(tabName); // Hitno: Odmah ažuriraj isticanje aktivnog taba
startTransition(() => {
setDisplayTab(tabName); // Ne-hitno: Ažuriraj prikazani sadržaj u tranziciji
});
};
const getTabContent = () => {
switch (displayTab) {
case 'tabA': return ;
case 'tabB': return ;
case 'tabC': return ;
default: return null;
}
};
return (
Primjer Prebacivanja Tabova
{isPending ? Učitavanje sadržaja taba...
: getTabContent()}
);
}
Objašnjenje: Ovdje, setActiveTab odmah ažurira vizualno stanje gumba tabova, dajući korisniku trenutnu povratnu informaciju da je njihov klik registriran. Stvarno renderiranje teškog sadržaja, kontrolirano s setDisplayTab, omotano je u tranziciju. To znači da sadržaj starog taba ostaje vidljiv i interaktivan dok se sadržaj novog taba priprema u pozadini. Jednom kada je novi sadržaj spreman, on neprimjetno zamjenjuje stari. Stanje isPending može se koristiti za prikazivanje indikatora učitavanja ili privremenog sadržaja.
Primjer 3: Odgođeno Dohvaćanje Podataka i Ažuriranja UI-ja
Prilikom dohvaćanja podataka s API-ja, posebno velikih skupova podataka, aplikacija će možda morati prikazati stanje učitavanja. Međutim, ponekad je trenutna vizualna povratna informacija interakcije (npr. klik na gumb 'učitaj više') važnija od trenutnog prikazivanja indikatora učitavanja dok se čeka na podatke.
Problem: Korisničko sučelje se zamrzava ili prikazuje naglo stanje učitavanja tijekom velikih učitavanja podataka iniciranih korisničkom interakcijom.
Rješenje: Ažurirajte stanje podataka nakon dohvaćanja unutar startTransition, pružajući trenutnu povratnu informaciju za akciju.
import React, { useState, experimental_useTransition } from 'react';
const fetchData = (delay) => {
return new Promise(resolve => {
setTimeout(() => {
const data = Array.from({ length: 20 }, (_, i) => `Nova stavka ${Date.now() + i}`);
resolve(data);
}, delay);
});
};
function DataFetcher() {
const [items, setItems] = useState([]);
const [isPending, startTransition] = experimental_useTransition();
const loadMoreData = () => {
// Simulacija trenutne povratne informacije za klik (npr. promjena stanja gumba, iako ovdje nije eksplicitno prikazano)
startTransition(async () => {
// Ova asinkrona operacija bit će dio tranzicije
const newData = await fetchData(1000); // Simulacija mrežnog kašnjenja
setItems(prevItems => [...prevItems, ...newData]);
});
};
return (
Primjer Odgođenog Dohvaćanja Podataka
{isPending && Dohvaćanje novih podataka...
}
{items.length === 0 && !isPending && Još nema učitanih stavki.
}
{items.map((item, index) => (
- {item}
))}
);
}
Objašnjenje: Kada se klikne gumb "Učitaj više stavki", poziva se startTransition. Asinkroni poziv fetchData i naknadno ažuriranje setItems sada su dio ne-hitne tranzicije. Stanje disabled gumba i tekst se odmah ažuriraju ako je isPending istina, dajući korisniku trenutnu povratnu informaciju o njegovoj akciji, dok korisničko sučelje ostaje potpuno responzivno. Nove stavke će se pojaviti kada se podaci dohvate i renderiraju, bez blokiranja drugih interakcija tijekom čekanja.
Najbolje Prakse za Korištenje experimental_useTransition
Iako moćan, experimental_useTransition treba koristiti promišljeno kako bi se maksimizirale njegove prednosti bez uvođenja nepotrebne složenosti.
- Identificirajte Stvarno Ne-hitna Ažuriranja: Najvažniji korak je ispravno razlikovati hitna i ne-hitna ažuriranja stanja. Hitna ažuriranja trebala bi se dogoditi odmah kako bi se održao osjećaj izravne manipulacije (npr. kontrolirana polja za unos, trenutna vizualna povratna informacija za klikove). Ne-hitna ažuriranja su ona koja se mogu sigurno odgoditi bez da se korisničko sučelje čini pokvarenim ili neresponzivnim (npr. filtriranje, teško renderiranje, rezultati dohvaćanja podataka).
-
Pružite Vizualnu Povratnu Informaciju s
isPending: Uvijek iskoristite zastavicuisPendingza pružanje jasnih vizualnih znakova svojim korisnicima. Suptilni indikator učitavanja, zatamnjeni odjeljak ili onemogućene kontrole mogu obavijestiti korisnike da je operacija u tijeku, poboljšavajući njihovo strpljenje i razumijevanje. To je posebno važno za međunarodnu publiku, gdje različite brzine mreže mogu učiniti percipirano kašnjenje različitim u različitim regijama. -
Izbjegavajte Prekomjernu Upotrebu: Ne treba svako ažuriranje stanja biti tranzicija. Omatanje jednostavnih, brzih ažuriranja u
startTransitionmože dodati zanemariv teret bez pružanja značajne koristi. Rezervirajte tranzicije za ažuriranja koja su zaista računalno intenzivna, uključuju složena ponovna renderiranja ili ovise o asinkronim operacijama koje mogu uvesti primjetna kašnjenja. -
Razumijte Interakciju sa
Suspense: Tranzicije izvrsno rade s ReactovimSuspense. Ako tranzicija ažurira stanje koje uzrokuje da se komponentasuspendira(npr. tijekom dohvaćanja podataka), React može zadržati staro korisničko sučelje na ekranu dok novi podaci ne budu spremni, sprječavajući da se naglo pojave prazna stanja ili rezervna korisnička sučelja. Ovo je naprednija tema, ali moćna sinergija. - Testirajte Responzivnost: Nemojte samo pretpostaviti da je `useTransition` popravio vaše zastajkivanje. Aktivno testirajte svoju aplikaciju pod simuliranim sporim mrežnim uvjetima ili s ograničenim CPU-om u alatima za razvojne programere preglednika. Obratite pažnju na to kako korisničko sučelje reagira tijekom složenih interakcija kako biste osigurali željenu razinu fluidnosti.
-
Lokalizirajte Indikatore Učitavanja: Kada koristite
isPendingza poruke o učitavanju, osigurajte da su te poruke lokalizirane za vašu globalnu publiku, pružajući jasnu komunikaciju na njihovom materinjem jeziku ako vaša aplikacija to podržava.
"Eksperimentalna" Priroda i Pogled u Budućnost
Važno je priznati prefiks experimental_ u experimental_useTransition. Ovaj prefiks ukazuje na to da, iako su temeljni koncept i API uglavnom stabilni i namijenjeni javnoj upotrebi, moglo bi doći do manjih promjena koje narušavaju kompatibilnost ili dorada API-ja prije nego što službeno postane useTransition bez prefiksa. Programeri se potiču da ga koriste i daju povratne informacije, ali trebaju biti svjesni ovog potencijala za male prilagodbe.
Prijelaz na stabilni useTransition (što se u međuvremenu dogodilo, ali za svrhu ovog posta, držimo se `experimental_` imenovanja) jasan je pokazatelj Reactove predanosti osnaživanju programera alatima za izgradnju istinski performantnih i ugodnih korisničkih iskustava. Konkurentni Način, s tranzicijama kao kamenom temeljcem, predstavlja temeljnu promjenu u načinu na koji React obrađuje ažuriranja, postavljajući temelje za naprednije značajke i obrasce u budućnosti.
Utjecaj na React ekosustav je dubok. Biblioteke i okviri izgrađeni na Reactu sve će više koristiti ove mogućnosti kako bi ponudili responzivnost "iz kutije". Programerima će biti lakše postići korisnička sučelja visokih performansi bez pribjegavanja složenim ručnim optimizacijama ili zaobilaznim rješenjima.
Uobičajene Zamke i Rješavanje Problema
Čak i s moćnim alatima poput experimental_useTransition, programeri se mogu susresti s problemima. Razumijevanje uobičajenih zamki može uštedjeti značajno vrijeme za debugiranje.
-
Zaboravljanje na
isPendingPovratnu Informaciju: Česta pogreška je korištenjestartTransitionbez pružanja ikakve vizualne povratne informacije. Korisnici bi mogli percipirati aplikaciju kao zamrznutu ili pokvarenu ako se ništa vidljivo ne mijenja dok je pozadinska operacija u tijeku. Uvijek uparite tranzicije s indikatorom učitavanja ili privremenim vizualnim stanjem. -
Omatanje Previše ili Premalo Sadržaja:
- Previše: Omatanje *svih* ažuriranja stanja u
startTransitionponištit će njegovu svrhu, čineći sve ne-hitnim. Hitna ažuriranja će se i dalje obrađivati prva, ali gubite razliku i možete imati manji teret bez ikakve koristi. Omotajte samo dijelove koji zaista uzrokuju zastajkivanje. - Premalo: Omatanje samo malog dijela složenog ažuriranja možda neće dati željenu responzivnost. Osigurajte da su sve promjene stanja koje pokreću težak rad na renderiranju unutar tranzicije.
- Previše: Omatanje *svih* ažuriranja stanja u
- Neispravno Identificiranje Hitnog naspram Ne-hitnog: Pogrešno klasificiranje hitnog ažuriranja kao ne-hitnog može dovesti do tromog korisničkog sučelja tamo gdje je najvažnije (npr. polja za unos). S druge strane, postavljanje zaista ne-hitnog ažuriranja kao hitnog neće iskoristiti prednosti konkurentnog renderiranja.
-
Asinkrone Operacije Izvan
startTransition: Ako pokrenete asinkronu operaciju (poput dohvaćanja podataka) i zatim ažurirate stanje nakon što jestartTransitionblok završen, to konačno ažuriranje stanja neće biti dio tranzicije. CallbackstartTransitiontreba sadržavati ažuriranja stanja koja želite odgoditi. Za asinkrone operacije, `await` i zatim `set state` trebali bi biti unutar callbacka. - Debugiranje Konkurentnih Problema: Debugiranje problema u konkurentnom načinu ponekad može biti izazovno zbog asinkrone i prekidive prirode ažuriranja. React DevTools pruža "Profiler" koji može pomoći u vizualizaciji ciklusa renderiranja i identificiranju uskih grla. Obratite pažnju na upozorenja i pogreške u konzoli, jer React često pruža korisne savjete vezane za konkurentne značajke.
-
Razmatranja o Upravljanju Globalnim Stanjem: Kada koristite biblioteke za upravljanje globalnim stanjem (poput Reduxa, Zustanda, Context API-ja), osigurajte da se ažuriranja stanja koja želite odgoditi pokreću na način koji omogućuje njihovo omatanje s
startTransition. To može uključivati dispečiranje akcija unutar callbacka tranzicije ili osiguravanje da vaši pružatelji konteksta interno koristeexperimental_useTransitionkada je to potrebno.
Zaključak
Hook experimental_useTransition predstavlja značajan korak naprijed u izgradnji visoko responzivnih i korisnički prijateljskih React aplikacija. Osnaživanjem programera da eksplicitno upravljaju prioritetom ažuriranja stanja, React pruža robustan mehanizam za sprječavanje zamrzavanja korisničkog sučelja, poboljšanje percipiranih performansi i pružanje dosljedno glatkog iskustva.
Za globalnu publiku, gdje su različiti mrežni uvjeti, mogućnosti uređaja i korisnička očekivanja norma, ova sposobnost nije samo lijep dodatak već nužnost. Aplikacije koje se bave složenim podacima, bogatim interakcijama i opsežnim renderiranjem sada mogu održavati fluidno sučelje, osiguravajući da korisnici diljem svijeta uživaju u besprijekornom i privlačnom digitalnom iskustvu.
Prihvaćanje experimental_useTransition i principa Konkurentnog Reacta omogućit će vam izradu aplikacija koje ne samo da besprijekorno funkcioniraju, već i oduševljavaju korisnike svojom brzinom i responzivnošću. Eksperimentirajte s njim u svojim projektima, primijenite najbolje prakse navedene u ovom vodiču i doprinesite budućnosti web razvoja visokih performansi. Putovanje prema korisničkim sučeljima bez zastajkivanja je uvelike u tijeku, a experimental_useTransition je moćan suputnik na tom putu.