Menu

React useContext Hook'u: Props Olmadan Veri Paylaşmak

useContext bir ebeveyn bileşenin sağladığı bir değeri okur; böylece derinde iç içe geçmiş bir bileşen, aradaki her bileşen onu prop olarak aşağı aktarmadan bu değeri alır. createContext'i, provider'ları, context'i bir çocuktan güncellemeyi ve context'in yeniden render'ları nasıl etkilediğini öğren.

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

useContext bir ebeveyn bileşenin sağladığı bir değeri okur; böylece ağacın derinlerindeki bir bileşen, aradaki her bileşen onu prop olarak aktarmadan bu değeri alabilir. createContext ile bir context oluşturur, ağacın bir kısmını bir value ile bir provider içine sarar ve o değere ihtiyaç duyduğun her yerde useContext(TheContext) çağırırsın.

Toolbar temadan hiç söz etmez, ama kutuyu işaretlediğinde iki düğme de değişir. Context'in bütün amacı budur: ortadaki bileşenler kullanmadıkları bir prop'u taşımaz; bu, context'in çözdüğü prop drilling sorunudur.

Üç adım

// 1. Create it once, outside any component, usually in its own file
export const ThemeContext = createContext('light');

// 2. Provide a value to a part of the tree
<ThemeContext value={theme}>
    <Page />
</ThemeContext>

// 3. Read it in any component inside that part
const theme = useContext(ThemeContext);

React 19'da context nesnesinin kendisi provider'dır. Eski kod <ThemeContext.Provider value={theme}> yazar, bu da hâlâ çalışır, bu yüzden ikisini de göreceksin.

useContext, o context'in en yakın provider'ını ağaçta yukarı doğru arar. Bir bileşen en yakın olanı okur, böylece bir bölüm için bir değeri geçersiz kılmak üzere provider'ları iç içe koyabilirsin.

Varsayılan değer

createContext'in argümanı, bileşenin üstünde hiç provider olmadığında useContext'in döndürdüğü şeydir. State değiştiğinde değişmez; bir yedektir.

İlk Greeting'in üstünde provider yoktur ve varsayılan 'en''i alır. İkincisi 'es''i, üçüncüsü ise daha yakındaki 'ja''yı okur. Dıştaki value="es"'i value="ja" yap; yalnızca ikinci satır değişir.

Context'i bir çocuktan güncellemek

Context yalnızca bir değeri aşağı aktarır. Derindeki bir çocuğun onu değiştirmesine izin vermek için değeri provider'ın olduğu yerde state olarak tut ve setter'ı context'e onun yanına koy.

LoginButton setUser'ı çağırır, App'teki state değişir, provider yeni bir değer alır ve Header da güncellenir. İki bileşen de bir prop almadı.

Değer değiştiğinde her tüketici yeniden render olur

Bir provider'ın value'su değiştiğinde React, onun için useContext çağıran her bileşeni render eder; o bileşen bir memo içinde durup props'u aynı kalmış olsa bile. React eski ve yeni değeri Object.is ile karşılaştırır. Yani value={{ user, setUser }}, App'in her render'ında yeni bir nesnedir ve user değişmemiş olsa bile her tüketici yeniden render olur.

İki okuyucu da ilk render'da bir kez kayıt yazar. Düğmeye tıkla: yalnızca PlainReader yeniden kayıt yazar, çünkü context'i yeni bir nesne aldı. useMemo, name değişene kadar MemoContext'e aynı nesneyi verir, bu yüzden MemoReader yerinde kalır. Bu yalnızca render yavaşlamaya başladığında önemlidir; küçük bir uygulama için her render'da yeni bir nesne sorun değildir.

Context'leri bölmek

Sık değişen bir değer ile hiç değişmeyen bir değer aynı context'i paylaşmamalıdır. Setter state ile birlikte duruyorsa, yalnızca setUser'ı çağırması gereken bir bileşen de user her değiştiğinde render olur. Onları iki context'e koy; her tüketici yalnızca okuduğuna abone olur:

const UserContext = createContext(null);
const SetUserContext = createContext(() => {});

function UserProvider({ children }) {
    const [user, setUser] = useState(null);
    return (
        <SetUserContext value={setUser}>
            <UserContext value={user}>{children}</UserContext>
        </SetUserContext>
    );
}

useState'ten gelen setUser kimliğini sonsuza kadar korur, bu yüzden yalnızca SetUserContext'i okuyan bileşenler bir oturum açma yüzünden asla render olmaz. Aynı fikir ilgisiz veriler için de geçerlidir: bir tema ve bir alışveriş sepeti tek bir büyük AppContext'e değil, ayrı context'lere aittir.

Yaygın bir son dokunuş, useContext(UserContext) çağıran ve provider eksik olduğunda açık bir hata fırlatan useUser() gibi bir özel hook'tur; böylece çağıranlar context nesnesini asla doğrudan import etmez.

Context, props ya da bir state kütüphanesi

  • Props varsayılandır. Bir değeri iki üç seviye aşağı aktarmak açıktır ve izlemesi kolaydır.
  • Context, birçok bileşenin birçok derinlikte ihtiyaç duyduğu ve nadiren değişen değerlere uyar: tema, dil, oturum açmış kullanıcı, bir özellik bayrağı nesnesi.
  • Bir state kütüphanesi (Redux Toolkit, Zustand, Jotai ve diğerleri), sık güncellenen büyük state'e uyar; bir bileşenin tek bir parçaya abone olmasını ve geri kalanının yol açtığı render'ları atlamasını istediğinde. Context'in böyle bir seçicisi yoktur: bir tüketici değerdeki her değişiklikte render olur.

Context'e ya da bir kütüphaneye başvurmadan önce bileşenleri children olarak aktarmanın drilling'i ortadan kaldırıp kaldırmadığını kontrol et. Çoğu zaman, hiç yeni API olmadan, kaldırır.

Sıkça Sorulan Sorular

React'te useContext ne yapar?

Bir context'in, ağaçta bileşenin üstündeki en yakın provider'dan alınan mevcut değerini döndürür. O provider'ın değeri değiştiğinde onu okuyan her bileşen yeniden render olur.

createContext'teki varsayılan değer ne işe yarar?

Bileşenin üstünde provider olmadığında useContext'in döndürdüğü şeydir. Testler ve kendi başına render edilen bileşenler için kullanışlıdır ve asla değişmez.

React 19'da hâlâ Context.Provider'a ihtiyacım var mı?

Hayır. React 19'da context'in kendisini provider olarak render edebilirsin: <ThemeContext value="dark">. <ThemeContext.Provider value="dark"> hâlâ çalışır, böylece eski kod çalışmaya devam eder.

Bir context değerini çocuk bileşenden nasıl güncellerim?

Değeri provider'ı render eden bileşende state olarak tut ve setter'ı context'e değerin yanına koy: value={{ theme, setTheme }}. Çocuk setTheme'i useContext ile okur ve çağırır.

React context, Redux'un yerini tutar mı?

Context bir değeri ağaçta aşağı aktarır; kendi başına state yönetmez. useState ya da useReducer ile birlikte birçok uygulamayı karşılar. Bir state kütüphanesi context'te olmayan şeyleri ekler; örneğin ilgisiz güncellemelerin bir bileşeni yeniden render etmemesi için tek bir parçaya abone olmak, ayrıca devtools ve middleware.

Coddy programlama dilleri çizimi

Coddy ile kodlamayı öğren

BAŞLA