07 / 12
Context
Prop drilling olmadan veri paylaşmak, use ile context okumak, reducer ile birlikte kullanmak ve sınırları.
Context Ne Çözer
Context, bir değeri aradaki component'lere prop olarak geçirmeden ağacın derinlerine ulaştırır. Bir component değeri sağlar (provide), altındaki herhangi bir component okur.1
Tipik kullanımlar: tema, oturum açmış kullanıcı, dil, sepet gibi uygulamanın geniş bir bölümünün ihtiyaç duyduğu ve seyrek değişen veriler.1
İpucu
Context'e uzanmadan önce Props ve composition dersindeki iki adımı deneyin: props ile devam edin ya da ara component'lere children verin. React dokümanı Context'i ancak bunlar yetmediğinde önerir.1
Üç Adım
import { createContext, use, useState } from "react";
type Theme = "light" | "dark";
// 1. Oluştur
const ThemeContext = createContext<Theme>("light");
// 2. Sağla
export function App() {
const [theme, setTheme] = useState<Theme>("light");
return (
<ThemeContext value={theme}>
<ProductPage />
<button onClick={() => setTheme(theme === "light" ? "dark" : "light")}>
Temayı değiştir
</button>
</ThemeContext>
);
}
// 3. Oku
function PriceTag({ amount }: { amount: number }) {
const theme = use(ThemeContext);
return <span className={`price price-${theme}`}>{amount} TL</span>;
}İki güncel ayrıntı:
React 19'dan beri provider olarak doğrudan
<ThemeContext value={...}>yazılır;<ThemeContext.Provider>hâlâ çalışır ama ileride deprecated olacak.2Context'i
useContextile deuseile de okuyabilirsiniz.use,ifiçinde ya da erkenreturn'den sonra da çağrılabilir;useContextçağrılamaz.3
Okuyan component, ağaçta kendisine en yakın provider'ın değerini alır. Provider yoksa createContext'e verilen varsayılan değeri görür.1
Provider'ı Custom Hook ile Sarmak
Context'in çoğu zaman anlamlı bir varsayılan değeri yoktur. Kent C. Dodds'un kalıbı: varsayılanı null yapın, context'i dışarı açmayın, okumak için provider yokken hata fırlatan bir hook export edin.4
const CartContext = createContext<CartContextValue | null>(null);
export function useCart() {
const cart = use(CartContext);
if (cart === null) {
throw new Error("useCart, CartProvider içinde kullanılmalı.");
}
return cart;
}Tip tarafı React'te tipler dersinde.
Reducer ile Birlikte
Context taşır, state tutmaz. Paylaşılan ve değişen bir veri için Context'i useState ya da useReducer ile birleştirirsiniz. React dokümanı state'i ve dispatch'i iki ayrı context'e koymayı önerir.5
const CartContext = createContext<CartItem[] | null>(null);
const CartDispatchContext = createContext<React.Dispatch<CartAction> | null>(null);
export function CartProvider({ children }: { children: React.ReactNode }) {
const [items, dispatch] = useReducer(cartReducer, []);
return (
<CartContext value={items}>
<CartDispatchContext value={dispatch}>{children}</CartDispatchContext>
</CartContext>
);
}dispatch hiç değişmez. Yalnızca "Sepete ekle" butonu gibi dispatch'e ihtiyaç duyan component'ler sepet değiştiğinde render olmaz.56
Performans ve Sınırlar
Provider'ın value'su değiştiğinde onu okuyan tüm component'ler render olur. Bu yüzden:67
Seyrek değişen veriyi koyun. Tema, kullanıcı ve dil iyi adaydır. Fare konumu ya da her tuşta değişen form değeri kötü adaydır.
İlgisiz değerleri ayırın. Tek dev bir
AppContextyerineThemeContext,UserContext,CartContext.Değeri her render'da yeniden oluşturmayın.
value={{ items, addItem }}her render'da yeni bir obje üretir. React Compiler bunu kendisi memoize eder; compiler yoksauseMemokullanın.7
Context bir state yönetim kütüphanesi değildir. TkDodo, Context'i değerin kendisi için değil, Zustand store'u ya da React Query client'ı gibi değişmeyen bir örneği paylaşmak için kullanmayı önerir; değer seçimini kütüphanenin selector'ları yapar.8 Sık değişen global client state için Zustand, sunucu verisi için TanStack Query rehberine bakın.
Next.js gibi Server Components kullanan bir framework'te Server Component Context oluşturamaz ama React 19.3'ten beri 'use client' modülünden import ettiği Context'i doğrudan render edebilir; ayrı bir Provider sarmalayıcısı gerekmez.9
Kendin Dene
ThemeContext'i kurun ve provider'ı silin.PriceTaghangi temayı gösteriyor?useCart'ı provider dışında çağırın ve hata mesajını görün.Sepete ekleme butonuna
console.log("render")koyun. Önce state vedispatch'i tek context'te, sonra iki ayrı context'te tutun ve sepete ürün eklerken logları sayın.Bir
if (!isOpen) return null;satırından sonrause(ThemeContext)çağırın; aynısınıuseContextile deneyip lint'in ne dediğine bakın.
Detaylı Öğrenmek İçin
Resmi doküman: "Passing Data Deeply with Context" ve "Scaling Up with Reducer and Context"; ikincisi sepet benzeri bir görev listesini adım adım kurar.15
Yazı: Kent C. Dodds'un "How to use React Context effectively" yazısı.4
Yazı: TkDodo'nun Zustand store'unu Context ile bir alt ağaca sınırlama yazısı.8
Kaynaklar
Context'in üç adımı, en yakın provider, kullanım alanları ve Context'ten önce denenecekler.
`<Context>`'in provider olarak kullanılması ve `<Context.Provider>`'ın ileride deprecated olacağı.
Context'i koşullu okuyabilen `use` ve `useContext` farkı.
: — 5 Haziran 2021. Provider dışında hata fırlatan custom hook ve context'i dışarı açmamak.
State ve `dispatch`'i ayrı context'lere koymak, provider component'i.
Değer değişince okuyan component'lerin render olması ve değeri memoize etmek.
: — 8 Mart 2021. Context değerini memoize etmek ve state ile dispatch'i ayırmak.
: — 14 Nisan 2024. Context ile değer yerine store örneğini paylaşmak.
9 Eylül 2026. Server Components'in Context'i doğrudan render edebilmesi.
Son güncelleme tarihi: 21 Ekim 2026
