useContext: özü, bağlam erişim hook'u ve React'te sağlayıcılar

Yazar: IT Sectr Yayınlanma: 2026-07-04 Okuma süresi: 9 dk

useContext, createContext ile oluşturulan bir bağlamdaki verilere işlevsel bileşenlerin doğrudan erişmesini sağlayan bir React hook'udur. React'te bağlam, props drilling sorununu — bu verileri kendileri kullanmayan birçok ara bileşen aracılığıyla props aktarma — çözer. React Documentation (2025)'a göre, useContext bir bağlam nesnesi alır ve bileşen ağacında yukarıdaki en yakın Provider tarafından ayarlanan geçerli değeri döndürür. Provider'daki değer değiştiğinde, useContext kullanan tüm bileşenler otomatik olarak yeniden oluşturulur.

Önemli Noktalar

  • useContext — props drilling olmadan React bağlamından değer okumak için hook.
  • createContext — varsayılan değer ve Provider bileşeni ile bağlam nesnesi oluşturur.
  • Provider — bağlam değerini tüm alt öğelere ileten bir sarmalayıcı bileşen.
  • Yeniden oluşturma — Provider değerinin değişmesi, tüm bağlam tüketicilerinin yeniden oluşturulmasını tetikler.
  • Ara bileşenleri atlama — useContext, verilerin birden çok iç içe geçme seviyesinden aktarılmasına izin verir.

React'te useContext Nedir

useContext, React 16.8'de diğer hook'larla birlikte eklenen, React bağlamından bir değer okumayı sağlayan bir hook'tur. Bağlam, her seviyede manuel olarak props aktarma ihtiyacı olmadan bileşen ağacı aracılığıyla veri aktarmak için tasarlanmış, React'e yerleşik bir mekanizmadır. useContext, eski Context API'nin Consumer bileşeninin yerini alır ve kodu daha öz ve okunabilir hale getirir.

Bağlamın tipik kullanım durumları arasında temalar (açık/koyu), yerel ayarlar ve çeviriler (i18n), kullanıcı kimlik doğrulaması, uygulama ayarları ve farklı iç içe geçme seviyelerindeki birçok bileşenin ihtiyaç duyduğu diğer küresel veriler bulunur. React ekibi, bağlamı bir bileşen alt ağacı için küresel olan veriler için kullanmayı önerir, ancak tüm uygulama için değil.

React Team — Bağlam dokümantasyonu (2025)'a göre, bağlamın yanlış kullanımı React uygulamalarındaki performans sorunlarının ana nedenlerinden biridir. Provider'daki her değer değişikliği, verinin hangi bölümünün değiştiğine bakılmaksızın tüm tüketicilerin yeniden oluşturulmasına neden olur. useMemo ve bağlam bölme yoluyla optimizasyon bu sorunu çözer.

jsx
import { createContext, useContext } from 'react';

// Varsayılan değerle bağlam oluştur
const ThemeContext = createContext('açık');

function ThemedButton() {
    const theme = useContext(ThemeContext);
    return <button className={`btn-${theme}`}>Click</button>;
}

React'te Bağlam Nasıl Çalışır

React'teki bağlam mekanizması, Provider-Consumer modeli aracılığıyla uygulanır. createContext, iki varlığı olan bir nesne döndürür: Provider — değeri ileten bir bileşen ve useContext'te kullanılan bağlam nesnesinin kendisi. Provider, bileşen ağacına monte edilir ve iç içe geçme derinliğine bakılmaksızın tüm alt öğelere değeri iletir.

React bir useContext çağrısıyla karşılaştığında, bu bağlam için en yakın Provider'ı bulmak üzere fiber ağacını dolaşır. Bir Provider bulunursa, değeri döndürülür. Hiçbir Provider bulunamazsa, createContext'e aktarılan varsayılan değer döndürülür. Bu arama her oluşturmada gerçekleşir, ancak fiber düğümü belleğe alma sayesinde çok hızlıdır ve performansı etkilemez.

React — Bağlam iç yapısı (2024)'a göre, useContext'in iç uygulaması, useState'e benzer şekilde bağlı bir hook listesi kullanır. Her hook, bir fiber düğümüne referans saklayarak React'in hangi Provider'ın bu bağlama karşılık geldiğini hızlıca belirlemesini sağlar. Bir Provider değerini güncellediğinde, React bu bağlamı kullanan tüm fiber düğümlerini yeniden oluşturma için işaretler.

Provider ve İç İçe Bağlamlar

Provider bileşenleri birbirinin içine yerleştirilebilir ve bir bağlam hiyerarşisi oluşturabilir. Her alt Provider, kendi alt ağacı için üst öğenin değerini geçersiz kılar. Bu, bir ekranın açık bir temaya ihtiyaç duyarken iç içe geçmiş bir modal pencerenin koyu bir temaya ihtiyaç duyması durumunda kullanışlıdır. useContext her zaman ağaçta yukarıdaki en yakın Provider'ın değerini döndürür.

jsx
const UserContext = createContext(null);
const ThemeContext = createContext('açık');

function App() {
    return (
        <UserContext.Provider value={{ name: 'Alice' }}>
            <ThemeContext.Provider value='dark'>
                <Profile />
            </ThemeContext.Provider>
        </UserContext.Provider>
    );
}

createContext ile Sağlayıcı Oluşturma

createContext(defaultValue) işlevi bir bağlam nesnesi oluşturur. defaultValue parametresi, bir bileşen useContext'i çağırdığında ancak ağaçta yukarıda karşılık gelen bir Provider olmadığında kullanılır. defaultValue olmadan, useContext undefined döndürür ve bu beklenmeyen hatalara yol açabilir. Her zaman anlamlı bir varsayılan değer veya null aktarılması önerilir.

Özel bir sağlayıcı oluşturmak, bağlam mantığını kapsüllemek için yaygın bir modeldir. Böyle bir sağlayıcının içinde, durum (useState veya useReducer aracılığıyla) saklanır ve Provider'ın value prop'u aracılığıyla sağlanır. Bu, uygulama ayrıntılarını tüketici bileşenlerden gizler ve bağlam yönetimi mantığını tek bir yerde merkezileştirir.

jsx
// Durum yönetimi ile özel Provider
const AuthContext = createContext(null);

function AuthProvider({ children }) {
    const [user, setUser] = useState(null);

    const login = useCallback(async (email, pass) => {
        const u = await loginApi(email, pass);
        setUser(u);
    }, []);

    return (
        <AuthContext.Provider value={{ user, login }}>
            {children}
        </AuthContext.Provider>
    );
}

Alt Bileşenlerde useContext Kullanımı

İşlevsel bileşenlerde, useContext bağlama erişmenin tek yoludur. Eski Context API'nin render-prop modelini gerektiren Consumer bileşeninin yerini alır: <ThemeContext.Consumer>{value => ...}</ThemeContext.Consumer>. useContext, özellikle tek bir bileşende birden çok bağlamla çalışırken kodu daha doğrusal ve okunabilir hale getirir.

Bir bileşende birden çok bağlam kullanırken, her bağlam için useContext'i birden çok kez çağırmanız yeterlidir. Her çağrı, ilgili Provider'ın değerini döndürür. Çağrıların sırası önemli değildir, çünkü her bağlam bağımsız bir varlıktır. React, aynı fiber referans sistemi aracılığıyla birden çok çağrıyı optimize eder.

jsx
function Dashboard() {
    const { user } = useContext(AuthContext);
    const theme = useContext(ThemeContext);
    const { locale } = useContext(I18nContext);

    return (
        <div className={`dashboard-${theme}`}>
            <h1>{locale.greeting}, {user.name}</h1>
        </div>
    );
}

useContext vs Redux: Ne Zaman Ne Seçilmeli

useContext ve Redux arasındaki seçim, durum yönetiminin ölçeğine ve karmaşıklığına bağlıdır. useContext + useReducer, küçük ve orta ölçekli uygulamalar için Redux'un hafif bir alternatifidir. Harici bir kütüphane kurulumu gerektirmez, öğrenmesi daha kolaydır ve çoğu görev için yeterlidir. Redux, middleware, geliştirici araçları ve değişmez güncellemelerle katı bir mimari gerektiğinde haklı çıkar.

Redux'un useContext'e göre ana avantajı, yeniden oluşturma optimizasyonudur. Varsayılan olarak, bir Provider'daki değer değiştiğinde, tüm bağlam tüketicileri yeniden oluşturulur. Redux, useSelector ve shallowEqual ile bileşenlerin durumun yalnızca belirli bölümlerine abone olmasını sağlar ve bu da büyük uygulamalarda yeniden oluşturma sayısını önemli ölçüde azaltır. Bağlam, birçok küçük bağlama bölünerek de optimize edilebilir.

KriteruseContextRedux
KarmaşıklıkHarici bağımlılık yokStore ve middleware kurulumu gerektirir
Yeniden oluşturmaHer değişiklikte tüm tüketicilerYalnızca belirli bir slice'a abone olanlar
DevToolsReact DevToolsZamanda yolculuk ile Redux DevTools
MiddlewareDesteklenmezRedux Thunk, Saga, Observable
Ne zaman seçilmeliOrta ölçekli uygulamalar, 3–5 bağlamKarmaşık iş mantığı olan büyük uygulamalar

Redux bakımcıları — Redux ne zaman kullanılmalı (2024)'a göre, React uygulamalarının %70'i Redux'a ihtiyaç duymaz. 50'den az bileşeniniz varsa ve durum önbelleğe alma, debounce ve yan etkilerle karmaşık mantık içermiyorsa — useContext + useReducer fazlasıyla yeterlidir. Redux, kalıplaşmış kod ekler ve bilinçli olarak kullanılmalıdır.

useContext ile Sık Yapılan Hatalar

En yaygın hata, her Provider oluşturmada value nesnesini yeniden oluşturmaktır. Provider'a value={{ user, login }} aktarırsanız, her Provider oluşturmada yeni bir nesne oluşturulur ve veriler değişmemiş olsa bile tüm tüketicilerin yeniden oluşturulmasına neden olur. Çözüm, değeri useMemo ile belleğe almak veya sık ve nadiren değişen veriler için ayrı bağlamlar kullanmaktır.

  • Gereksiz yeniden oluşturmalar — her Provider oluşturmada yeni bir value nesnesi. Değeri belleğe almak için useMemo kullanın.
  • Çok büyük bağlam — düzinelerce alanı olan tek bir Provider, herhangi bir alan değiştiğinde tüm alt bileşenlerin yeniden oluşturulmasına neden olur. Anlamlarına göre birden çok bağlama bölün.
  • defaultValue eksikliği — hiçbir Provider bulunamazsa, useContext defaultValue döndürür ve bu undefined ise, her çağrı bir TypeError fırlatır.
  • Aynı türden iç içe Provider'lar — derin seviyelerde bağlamı geçersiz kılmak kafa karıştırıcı olabilir ve beklenmeyen değerlere yol açabilir.
jsx
// ❌ Her oluşturmada yeni nesne — tüm tüketiciler yeniden oluşturulur
<AuthContext.Provider value={{ user, login }}>{children}</AuthContext.Provider>

// ✅ Belleğe alınmış değer — yalnızca user veya login değiştiğinde yeniden oluştur
const authValue = useMemo(() => ({ user, login }), [user, login]);
<AuthContext.Provider value={authValue}>{children}</AuthContext.Provider>

“Büyük bağlam” sorununu çözmek için, küresel durumu mantıksal gruplara ayırın: AuthContext, ThemeContext, I18nContext. Her bağlam kendi alanından sorumludur ve bağımsız olarak güncellenir. Bu, useMemo aracılığıyla devasa bir bağlamı optimize etmeye çalışmaktan daha basittir ve daha öngörülebilir bir yeniden oluşturma davranışı sağlar.

Sıkça Sorulan Sorular

Bağlam alt bileşenden değiştirilebilir mi?

Evet, Provider'ın value'sunda bir değiştirici işlev aktarırsanız. Tipik model, durumu Provider'da saklamak ve useContext aracılığıyla hem verileri hem de güncelleme işlevlerini aktarmaktır. Alt bileşenler bu işlevleri çağırır ve Provider'daki durum değişikliği otomatik olarak tüm tüketicileri günceller. Bu, küçük uygulamalar için temel bir Redux alternatifidir.

Hangisi daha hızlı — useContext mi Redux mu?

Basit senaryolarda, useContext store ve middleware yükünün olmaması nedeniyle daha hızlıdır. Ancak sık güncellemeler ve çok sayıda tüketici ile Redux kazanır çünkü seçicileri (useSelector) durumun yalnızca belirli bölümlerine abone olurken, useContext her değişiklikte tüm tüketicileri yeniden oluşturur. Yüksek güncelleme sıklığı olan uygulamalar (animasyonlar, gerçek zamanlı) için Redux veya özel kütüphaneleri seçin.

useContext bir React bileşeni dışında kullanılabilir mi?

Hayır. useContext, tüm hook'lar gibi, yalnızca bir React işlevsel bileşeni veya özel bir hook içinde çağrılabilir. Normal bir işlevde (örneğin, bir yardımcı program veya hizmette) bağlam değerini almanız gerekiyorsa, bileşenden parametre olarak aktarın veya React dışında küresel duruma sahip ayrı bir modül kullanın.

TypeScript ile useContext nasıl çalışır?

TypeScript'te bağlam tiplemesi, createContext'te tür belirtilerek yapılır: createContext<AuthContextType | null>(null). Bu, useContext(AuthContext)'in doğru türde bir değer döndürmesini garanti eder. Kullanışlı bir model, useContext'i çağıran, null'ı kontrol eden ve net bir hata fırlatan özel bir useAuth hook'u oluşturmaktır: “useAuth, AuthProvider içinde kullanılmalıdır”.

Provider varken neden useContext undefined döndürüyor?

En yaygın neden, tüketici bileşenin ilgili Provider'ın içinde olmamasıdır. Provider'ın, useContext'in kullanıldığı tüm alt ağacı sardığını kontrol edin. İkinci neden — Provider'a farklı bir bağlam nesnesi aktarılmıştır: geliştirici createContext'i çağırarak bir bağlam oluşturur ancak useContext'i farklı bir createContext örneği ile kullanır.

Özet

  • useContext — React bağlamından değer okumak için hook, props drilling ihtiyacını ortadan kaldırır.
  • createContext — veri aktarmak için Provider ve Provider olmayan durumlar için defaultValue ile bağlam nesnesi oluşturur.
  • Değeri belleğe alın — gereksiz tüketici yeniden oluşturmalarını önlemek için Provider'ın değeri için useMemo kullanın.
  • Bağlamları bölün — küresel durumu mantıksal gruplara göre birden çok küçük bağlama ayırın.
  • Provider hiyerarşisi — ağacın bir bölümünde değerleri geçersiz kılmak için aynı türden Provider'lar iç içe yerleştirilebilir.
  • useContext + useReducer — harici bağımlılıklar olmadan orta ölçekli uygulamalar için hafif Redux alternatifi.
  • Redux'un yerini almaz — middleware ve sık güncellemelerle karmaşık mantık için seçicilerle Redux'u seçin.

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun