İçeriğe geç

State Nerede Yaşamalı? — Bileşen, Üst Bileşen, Context, Cache, URL

Orta 9 dk Çok sık karşılaşılır

Önce şunu oku: React Render Modeli

30 saniyede özet

Her state'i tek bir global yere koymak kolay görünür, ama yeniden çizim fırtınası, kaybolan filtreler ve bayat sunucu verisi getirir. Her parça için üç soru sor: kimler kullanıyor, sunucudan mı geliyor, paylaşılabilir mi olmalı?

Evinde her şeyi salona yığdığını düşün: diş fırçası, kumanda, süt, ev adresinin yazılı olduğu kâğıt. Her şeyi bulmak kolay gibi görünür, çünkü hepsi tek yerde. Ama salon kısa sürede kimsenin oturamadığı bir depoya döner.

  1. Bayt: Bankacılık uygulamasında bütün state'i tek bir global context'e koyduk. Her şey tek yerde!

  2. Sen: Tutar alanına yazınca bütün ekran takılıyor. Filtre de yenilemede kayboluyor.

  3. Bayt: Bir de başka sekmede havale yapınca bakiye eski kalıyor...

  4. Bayt: Belki her parçanın ayrı bir yeri olmalı. Tek tek bakalım.

Kim kullanıyor?

Yalnızca bir bileşen kullanıyorsa state onun içinde yaşar. Havale formunda yazılan tutar böyledir: başka hiçbir ekranı ilgilendirmez.

İki kardeş bileşen aynı değeri paylaşıyorsa, state ortak üst bileşene taşınır: lifting state upİki kardeş bileşenin paylaştığı state'i ortak üst bileşenlerine taşımak. Üst bileşen değeri props ile ikisine de verir; ikisi hep aynı şeyi gösterir.Sözlükte gör →. Üst bileşen değeri props ile ikisine de verir ve ikisi hep aynı şeyi gösterir.

Kafam karıştı, daha basit anlat

Tek kullanan varsa onun içinde. İki kardeş paylaşıyorsa ortak üst bileşende.

Hızlı kontrolBaşlangıç

Yalnızca havale formunun kullandığı, yazılan tutar nerede yaşamalı?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Üst bar ve havale formu aynı seçili hesabı göstermeli. Seçim nerede yaşamalı?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Global neden her şey değil?

Yazılan tutar, 12 bileşenin okuduğu global bir context'te tutuluyor. Kullanıcı 6 hane yazdı. Kaç bileşen yeniden çizilir? Cevabı göster

Her tuşta 12, toplam 72. Context değeri değişince onu okuyan her bileşen yeniden çizilir. Tutar yalnızca formdaysa her tuşta 1 bileşen, toplam 6 çizim yeter.

Her şey onu kullananlara en yakın yerde.
Adım adım oku
  1. Her şeyi salona yığmak: dağınıklık.
  2. Diş fırçası kendi banyonda, kumanda salonda.
  3. Sütün tarihi kutuda, ev adresi kapıda.
  4. Her şey onu kullananlara en yakın yerde.

contextReact'te bir değeri props zinciri olmadan derindeki bileşenlere ulaştıran yol. Değer değişince onu okuyan her bileşen yeniden çizilir.Sözlükte gör →, uygulamanın her yerinden okunan ve az değişen değerler içindir: tema, dil, oturumdaki kullanıcı. Sık değişen bir değeri oraya koyarsan, okuyan her bileşen her değişiklikte yeniden çizilir.

Sunucudan gelen bakiye ise başka bir türdür: sunucu state'iAsıl sahibi sunucu olan veri: bakiye, hareketler. Ekranda tutulan hâli bir önbellektir; başka bir yerde değişince bayatlar ve yeniden istenmelidir.Sözlükte gör →. Onun asıl sahibi sunucudur; ekrandaki elle tutulan kopya, başka bir sekmede havale yapılınca bayatlar. Bir query cache onu yeniden ister.

Paylaşılması gereken bir filtre ise URL’de yaşar, böylece yenilemede ve linkte kalır.

Kafam karıştı, daha basit anlat

Context az değişen genel değerler için. Sunucu verisi cache’te, paylaşılacak görünüm URL’de.

Hızlı kontrolOrta

Sık değişen bir değeri 12 bileşenin okuduğu bir context'e koymanın bedeli nedir?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Sunucudan gelen bakiyeyi bir query cache'e bırakmanın faydası nedir?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Kendin gör

State nerede yaşamalı?

Tohum 561119
  1. Havale formunda yazılan tutar

    Yeri: Global context

    Senaryo: Kullanıcı tutar alanına 6 hane yazdı

    · bekliyor

  2. Seçili hesap (üst bar ve form)

    Yeri: Global context

    Senaryo: Kullanıcı üst bardan başka bir hesap seçti

    · bekliyor

  3. Hareket listesi filtresi

    Yeri: Global context

    Senaryo: Sayfa yenilendi ve link bir iş arkadaşına gönderildi

    · bekliyor

  4. Hesap bakiyesi (sunucudan)

    Yeri: Global context

    Senaryo: Başka bir sekmede havale yapıldı, bu sekmeye dönüldü

    · bekliyor

Her parçanın yerini yukarıdan seç, sonra oynat: her adım bir senaryo.

Hız
Adım 0

Şu an ne oldu?

Hepsi: Global context

Dört senaryo oynanacak; her biri bir parçanın yerini sınayacak.

Görevler0/3

  • Tutarı yazarken 72 yeniden çizim yaptıraçık

    İpucu

    Varsayılan ayarlar yeter.

  • Bakiyeyi bayatlataçık

    İpucu

    Sunucu verisini elle tut.

  • Dört senaryoyu da sorunsuz geçiraçık

    İpucu

    Her parça için: kimler kullanıyor, nereden geliyor?

Olay günlüğü (0)

Henüz olay yok. Oynat veya adımla.

  1. Varsayılanla oynat. Her şey global context’te: hiçbir senaryo sorunsuz geçmedi.
  2. Tutarı “Bileşenin kendi state’i”ne al. 72 yeniden çizim 6’ya indi.
  3. Seçili hesabı önce “Bileşenin kendi state’i”ne, sonra “Ortak üst bileşen”e al. İlkinde üst bar ile form ayrıştı, ikincisinde aynı kaldı.
  4. Filtreyi “URL”ye, bakiyeyi “Sunucu cache’i”ne al. Dört senaryo da sorunsuz.
Hızlı kontrolOrta

Hareket listesinin filtresi yenilemede kayboluyor. Çözüm nedir?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Seçili hesap iki kardeş bileşende ayrı ayrı useState ile tutuluyor. Kullanıcı üst bardan hesap değiştirdi. Ne olur?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Tuzaklar

Sunucu verisini kopyalamak. Bakiyeyi bir kez çekip useState’e koymak, onu sunucudan koparır. Sunucu verisini bir query cache’e bırak ve bir değişiklikten sonra o kaydı geçersiz kıl.

Türetilebilen değeri state’te tutmak. Hareketlerin toplamı, hareket listesinden hesaplanabilir. Ayrı bir state’te tutarsan ikisi bir gün uyuşmaz; her çizimde hesapla.

Prop’ları on kat aşağı taşımak. Bir değeri ona hiç bakmayan beş bileşenin içinden geçirmek de bir sinyaldir. Değer gerçekten genelse context’e, değilse onu kullanan bileşene daha yakın bir yere taşı.

Kafam karıştı, daha basit anlat

Sunucu verisini kopyalama, türetileni hesapla, prop zincirini kısalt.

Hızlı kontrolOrta

Hareketlerin toplamı ayrı bir state'te tutuluyor ve bir gün listeyle uyuşmuyor. Ne yapılmalı?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Aşağıdaki örnek bir bankacılık uygulamasından: formda yerel tutar, ortak üstte seçili hesap, URL’de filtre ve query cache’te bakiye.

Derinleş · Bankacılık uygulaması: dört state, dört ayrı yer 4 dosya · ~56 satır · ilk okumada atlayabilirsin
Proje dosyaları

src/app/transfer/ TransferForm.tsx Form: yazılan tutar yalnızca formun içinde; her tuşta yalnızca form çiziliyor.

src/app/transfer/TransferForm.tsx
export function TransferForm({ accountId }: { accountId: string }) {
const [amount, setAmount] = useState(''); // only this form cares about the typed amount
const queryClient = useQueryClient();
async function submit() {
await sendTransfer({ from: accountId, amount });
// The balance belongs to the server: mark it stale instead of editing a copy.
await queryClient.invalidateQueries({ queryKey: ['balance', accountId] });
setAmount('');
}
return (
<form onSubmit={(e) => { e.preventDefault(); void submit(); }}>
<input inputMode="decimal" value={amount} onChange={(e) => setAmount(e.target.value)} aria-label="Tutar" />
<button type="submit">Gönder</button>
</form>
);
}

src/app/accounts/ AccountsLayout.tsx Düzen: seçili hesap üst bar ile formun ortak üst bileşeninde; ikisi hep aynı hesabı gösteriyor.

src/app/accounts/AccountsLayout.tsx
export function AccountsLayout({ accounts }: { accounts: Account[] }) {
// Two siblings need the same selection: it lives in their nearest common parent.
const [selectedId, setSelectedId] = useState(accounts[0]!.id);
return (
<>
<AccountSwitcher accounts={accounts} selectedId={selectedId} onSelect={setSelectedId} />
<BalanceCard accountId={selectedId} />
<TransferForm accountId={selectedId} />
</>
);
}

src/app/transactions/ TransactionsPage.tsx Hareketler: filtre URL'de; yenilemede ve paylaşılan linkte kalıyor.

src/app/transactions/TransactionsPage.tsx
export function TransactionsPage({ accountId }: { accountId: string }) {
// The filter is part of the address: it survives a refresh and travels with a link.
const [params, setParams] = useSearchParams();
const direction = params.get('yon') ?? 'hepsi';
return (
<>
<select value={direction} onChange={(e) => setParams({ yon: e.target.value })} aria-label="Yön">
<option value="hepsi">Hepsi</option>
<option value="giden">Giden</option>
<option value="gelen">Gelen</option>
</select>
<TransactionList accountId={accountId} direction={direction} />
</>
);
}

src/app/accounts/ BalanceCard.tsx Bakiye: query cache'te; sekmeye dönünce yeniden isteniyor, havaleden sonra geçersiz kılınıyor.

src/app/accounts/BalanceCard.tsx
export function BalanceCard({ accountId }: { accountId: string }) {
// Server state: the cache owns it, refetches when the tab regains focus, and shares it.
const { data, isPending } = useQuery({
queryKey: ['balance', accountId],
queryFn: () => fetchBalance(accountId),
});
if (isPending) return <p>Bakiye yükleniyor…</p>;
return <p>Bakiye: {formatTry(data!.amount)}</p>;
}

Kendini sına

Şimşek turu1/4

Yalnızca bir bileşenin kullandığı değer o bileşenin içinde yaşamalıdır.

Soru 1/3İleri

Havale gönderildikten sonra bakiye ekranda eski kalıyor; bakiye bir query cache'te. Eksik olan nedir?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Aklında kalacak üç şey

  1. 1 State'i onu kullanan bileşenlere en yakın yere koy. Yalnızca bir bileşen kullanıyorsa onun içinde, iki kardeş paylaşıyorsa ortak üst bileşende yaşamalı.
  2. 2 Sunucudan gelen veri bir kopya değil, bir önbellektir. Onu bir query cache'e bırakırsan yeniden ister, bayatlamaz ve birden çok ekran aynı kaydı paylaşır.
  3. 3 Yenilemede kalması ya da bir linkle paylaşılması gereken görünüm, örneğin bir filtre, URL'de yaşamalı.
Sonraki kapı IBAN'ın ilk iki harfini yazdın ve form daha sen bitirmeden kırmızıya döndü. Yanlış bir şey mi yaptın? Form Doğrulama — Hatayı Ne Zaman Göstermeli? · 9 dk

4 kart sonraki derste seni bekliyor

0/4 kart bu dersten toplandı

Bu dersin üstüne kurulanlar

Bunlar bu dersi temel alıyor; hazır olduğunda devam edebilirsin.