Menu

React useTransition Hook'u: Arayüzü Akıcı Tutmak

useTransition bir state güncellemesini acil değil olarak işaretler; böylece React yavaş kısmı arka planda render ederken sayfayı akıcı tutabilir. isPending'i, startTransition'ı, React 19'daki async transition'ları ve bunun neden debounce olmadığını öğren.

Bu sayfada çalıştırılabilir editörler var - düzenle, çalıştır ve sonucu anında gör.

useTransition, bir state güncellemesini acil değil olarak işaretlemeni sağlar. React bu güncellemeyi arka planda render eder ve bir tıklama ya da tuş vuruşu gibi daha acil bir şey olursa onu bırakır ya da yeniden başlatır; böylece ekranın yavaş bir kısmı yetişirken sayfa akıcı kalır.

posts'a tıkla, sonra liste görünmeden contact'a tıkla. Contact hemen görünür: React yarım kalmış posts render'ını attı. Şimdi startTransition(() => { setTab(next); }) ifadesini düz bir setTab(next); yap ve aynısını dene: posts'a tıkladıktan sonra sayfa yaklaşık 300 ms donar ve contact'a tıklaman posts bitene kadar bekler.

Sözdizimi

const [isPending, startTransition] = useTransition();

startTransition(() => {
    setTab(next);
});
  • startTransition bir fonksiyon alır ve onu hemen çalıştırır. İçindeki tüm state güncellemeleri transition olarak işaretlenir.
  • isPending, transition'ı başlattığın andan React onu render etmeyi bitirip sonucu commit edene kadar true'dur.

useTransition argüman almaz. Aktardığın fonksiyon senkron çalışır; transition, fonksiyonunun ne zaman çalıştığıyla değil, React'in ortaya çıkan güncellemeyi nasıl render ettiğiyle ilgilidir.

"Acil değil" ne demek

React güncellemeleri iki türe ayırır. Yazmak, tıklamak ve basmak gibi acil güncellemelerin hemen yansıması gerekir, yoksa sayfa bozuk hissettirir. Yeni bir görünüme geçmek ya da filtrelenmiş sonuçları göstermek gibi transition güncellemeleri biraz zaman alabilir.

React bir transition'ı küçük dilimler hâlinde render eder ve bileşenler arasında acil bir şeyin gelip gelmediğini kontrol eder. Geldiyse React transition'ı duraklatır ya da bırakır, acil güncellemeyi ele alır ve sonra transition'ı en son state ile yeniden başlatır. Bir transition render edilirken önceki ekran ayakta kalır; React yarı inşa edilmiş bir sonuç göstermez. Örneğin posts hazır olana kadar düğmelerin yanında Loading ipucuyla about metnini göstermeye devam etmesinin nedeni budur.

Yarıda kesme bileşenler arasında olur. 300 ms boyunca kilitlenen tek bir bileşen ikiye bölünemez; yukarıdaki yavaş işin 300 küçük SlowPost bileşenine yayılmasının nedeni budur.

Bir bekleme ipucu göstermek

isPending, mevcut içeriğin yerini almayan bir yükleme göstergesinin yeridir: düğmenin yanında bir spinner, soluklaştırılmış metin, bir "Saving..." etiketi. İlk örnekte sekmelerin yanında Loading... gösteriyor. Onu içeriği stillendirmek için de kullanabilirsin:

<div style={{ opacity: isPending ? 0.6 : 1 }}>{content}</div>

Yazarken büyük bir listeyi filtrelemek

Bir input'un kendi değerini bir transition'a koyamazsın. Kontrollü bir <input> yeni değerini aynı acil güncellemede almalıdır, yoksa karakterler düşer. Bunun yerine iki state parçası tut: input'un metni (acil) ve listenin kullandığı sorgu (bir transition).

Hızlıca 123 yaz. Input hiç takılmaz. Console yine her tuş vuruşu için bir rendering results satırı kaydeder, çünkü Results React onu render etmeye başlar başlamaz kayıt yazar, ama 1 ve 12 için listeler ekrana hiç ulaşmaz: her yeni tuş vuruşu devam eden render'ı kesti ve React en son sorguyla yeniden başladı. Results bilerek memo ile sarılmıştır: o olmadan her tuş vuruşunun acil render'ı yavaş listeyi eski sorguyla da render ederdi ve faydayı kaybederdin.

Hook olmadan startTransition

react ayrıca startTransition'ı düz bir fonksiyon olarak export eder. Güncellemeleri tıpkı hook gibi transition olarak işaretler, ama isPending almazsın. Onu bir hook çağıramadığın yerde kullan, örneğin herhangi bir bileşenin dışındaki bir veri kütüphanesinde ya da bir yönlendiricide.

import { startTransition } from 'react';

function navigate(url) {
    startTransition(() => {
        setCurrentUrl(url);
    });
}

React 19'da async transition'lar

React 19'dan beri aktardığın fonksiyon async olabilir. O zaman isPending, bekleme dahil fonksiyonun çalıştığı tüm süre boyunca true kalır; bu da bir istek sırasında bekleme durumu göstermenin basit bir yoludur. Aşağıdaki sahte saveName gerçek bir isteğin yerine geçer.

setSaved etrafındaki ikinci startTransition'a dikkat et. React bir await boyunca transition'ın izini kaybeder, bu yüzden ondan sonraki bir state güncellemesinin transition'ın parçası sayılması için yeniden sarılması gerekir. React bu şekilde aktarılan bir fonksiyona action der; useActionState ve form action'ları aynı mekanizmanın üzerine kuruludur.

Bir transition debounce değildir

Bir debounce, son tuş vuruşundan sonra bir şey yapmadan önce sabit bir süre bekler. Bir transition beklemez. Hemen render etmeye başlar ve daha yeni bir güncelleme gelirse eski işi bırakır. Hızlı bir cihazda sonuç hiç gecikmeden görünür; yavaş bir cihazda React tuş vuruşları arasında yapabildiği kadarını yapar. Bir transition'ın yapamadığı şey ağ isteklerinin sayısını azaltmaktır: her tuş vuruşu bir istek başlatıyorsa isteğe debounce uygula.

Transition'lar ve Suspense

Transition'lar bir Suspense sınırının ne yaptığını da değiştirir. Normalde bir sınırın içindeki bir bileşen askıya alındığında (yüklenen lazy bir bileşen ya da use ile okunan veri) React içeriği yedek içerikle değiştirir. Askıya almaya yol açan güncelleme bir transition idiyse React bunun yerine ekranda zaten olan içeriği tutar ve isPending yeni içerik hazır olana kadar true kalır. Yönlendiriciler her gezinmede sayfa boyutunda bir spinner parlatmaktan böyle kaçınır: gezinmeyi bir transition'a sararlar ve eski sayfa bir sonraki render edilebilene kadar görünür kalır. Hiç gösterilmemiş içerik yine yedek içeriği kullanır, bu yüzden yeni ortaya çıkan bir sınır her zamanki gibi davranır.

Çalışmayan şeyler

  • Bir timeout içindeki güncellemeler. startTransition(() => setTimeout(() => setTab(next), 100)) güncellemeyi işaretlemez, çünkü startTransition döndükten sonra çalışır. Bunun yerine startTransition'ı timeout'un içine koy.
  • Tek bir yavaş bileşen. React yalnızca bileşenler arasında kesebilir, bu yüzden uzun süre kilitlenen tek bir bileşen yine kilitler.
  • Bir input'u kontrol etmek. Yukarıdaki gibi, input'un kendi state'i acil kalır.

State setter'ına sahip olmadığın ve yalnızca bir prop gibi bir değer aldığın durum için useDeferredValue sana aynı davranışı verir.

Sıkça Sorulan Sorular

useTransition ne yapar?

Sana içindeki state güncellemelerini acil değil olarak işaretleyen startTransition'ı ve o güncelleme hâlâ render edilirken true olan isPending'i verir. React, önce tıklamaları ve yazmayı ele almak için acil olmayan bir render'ı yarıda kesebilir.

useTransition ile startTransition arasındaki fark nedir?

İkisi de güncellemeleri transition olarak işaretler. useTransition hook'u ayrıca bir yükleme ipucu için sana isPending verir. react'ten import edilen bağımsız startTransition bileşenlerin dışında çalışır ama bekleme bayrağı yoktur.

useTransition'ı bir metin input'u için kullanabilir miyim?

Input'un kendi değeri için hayır. Kontrollü bir input senkron olarak güncellenmelidir, yoksa yazma bozulur. Input'un state'ini acil tut ve ona bağlı pahalı güncellemeyi bir transition'a koy ya da useDeferredValue kullan.

useTransition debounce ile aynı şey mi?

Hayır. Bir debounce bir şey yapmadan önce sabit bir süre bekler. Bir transition hemen render etmeye başlar ve daha yeni bir güncelleme gelirse yarıda kesilir, bu yüzden hızlı bir cihazda sonuç hiç gecikmeden görünür.

startTransition async bir fonksiyon alabilir mi?

Evet, React 19'dan beri. isPending, async fonksiyon bitene kadar true kalır. Bir await'ten sonraki state güncellemelerinin transition olarak işaretlenmesi için başka bir startTransition çağrısıyla sarılması gerekir.

Coddy programlama dilleri çizimi

Coddy ile kodlamayı öğren

BAŞLA