React İle Context Api Kullanarak Global Tema Değiştirici Nasıl Yapılır?

Ön Hazırlık ve Gereksinimler

Bu uygulamayı hayata geçirmek için temel düzeyde React ve Hooks (kancalar) bilgisine sahip olmanız yeterlidir. Projenizde modern bir geliştirme ortamı kullandığınızdan emin olun.

  • Node.js (LTS sürümü) yüklü olmalıdır.
  • React 18 veya üzeri bir sürüm kullanılması önerilir.
  • Projenizde CSS veya Tailwind CSS gibi bir stil kütüphanesinin kurulu olması gerekir.

Başlamadan önce terminalinizde yeni bir React projesi oluşturabilir veya mevcut projenize devam edebilirsiniz:

npx create-react-app tema-uygulamasi
cd tema-uygulamasi
npm start

Bu komutlar, geliştirme ortamınızı ayağa kaldıracak ve tarayıcınızda uygulamanızın canlı önizlemesini görmenizi sağlayacaktır.

Adım 1: Tema Context Yapısını Oluşturma

Context API kullanırken ilk adım, verinin tutulacağı "Context" nesnesini oluşturmaktır. Bu nesne, uygulamanın geri kalanına tema bilgisini ve tema değiştirme fonksiyonunu sağlayacaktır.

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

const ThemeContext = createContext();

export const ThemeProvider = ({ children }) => {
  const [theme, setTheme] = useState('light');

  const toggleTheme = () => {
    setTheme((prev) => (prev === 'light' ? 'dark' : 'light'));
  };

  return (
    
      {children}
    
  );
};

export const useTheme = () => useContext(ThemeContext);

Burada createContext ile bir bağlam oluşturduk. ThemeProvider bileşeni, uygulamanın sarmalayacağı tüm bileşenlere theme değerini ve toggleTheme fonksiyonunu aktarır. useTheme kancası ise bu değerlere kolayca erişmemizi sağlar.

Adım 2: Uygulamayı Provider İle Sarmalama

Oluşturduğumuz ThemeProvider bileşeninin, tema verisinin global olarak erişilebilir olması için uygulamanın en üst seviyesinde (genellikle index.js veya App.js) kullanılması gerekir.

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { ThemeProvider } from './context/ThemeContext';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  
    
  
);

Bu işlem, App bileşeni ve onun altındaki tüm bileşenlerin useTheme kancasını kullanarak tema verisine erişebilmesini sağlar.

Adım 3: Tema Değiştirici Bileşenini Hazırlama

Kullanıcının temayı değiştirmesi için bir arayüz bileşenine ihtiyacımız var. Bu bileşen, useTheme kancasını çağırarak mevcut durumu okuyacak ve toggleTheme fonksiyonunu tetikleyecektir.

import { useTheme } from './context/ThemeContext';

const ThemeToggler = () => {
  const { theme, toggleTheme } = useTheme();

  return (
    
      Şu anki tema: {theme === 'light' ? 'Açık' : 'Koyu'}
    
  );
};

Bu basit buton, her tıklandığında toggleTheme fonksiyonunu çalıştırarak ThemeContext içindeki durumu günceller ve React'in tekrar render (yeniden çizim) yapmasını tetikler.

Adım 4: Stil Yönetimi ve CSS Entegrasyonu

Tema değişikliğinin görselleşmesi için CSS değişkenlerini veya koşullu sınıf isimlerini kullanabiliriz. En temiz yöntem, kök (root) seviyesinde bir sınıf atamaktır.

// App.js içinde
import { useTheme } from './context/ThemeContext';
import './App.css';

function App() {
  const { theme } = useTheme();

  return (
    

React Tema Uygulaması

); }

CSS dosyanızda ise şu şekilde tanımlamalar yapabilirsiniz:

.app-container.light { background-color: #ffffff; color: #000000; }
.app-container.dark { background-color: #1a1a1a; color: #ffffff; }

Adım 5: Kalıcı Tema Tercihi (LocalStorage)

Kullanıcı sayfayı yenilediğinde temanın sıfırlanmasını istemeyiz. Bu nedenle tercihi localStorage üzerinde tutmak en iyi uygulamadır.

Güvenlik Uyarısı: localStorage üzerinde hassas kullanıcı verileri saklamayın. Tema tercihi gibi genel ayarlar için kullanımı güvenlidir ancak XSS saldırılarına karşı her zaman kullanıcı girdilerini temizlediğinizden emin olun.

// ThemeContext.js içinde güncelleme
const [theme, setTheme] = useState(localStorage.getItem('theme') || 'light');

const toggleTheme = () => {
  const newTheme = theme === 'light' ? 'dark' : 'light';
  setTheme(newTheme);
  localStorage.setItem('theme', newTheme);
};

Yöntem Karşılaştırması

Yöntem Avantaj Dezavantaj
Context API Dahili çözüm, ek paket gerektirmez. Çok sık güncellemelerde performans kaybı olabilir.
Redux Toolkit Büyük ölçekli state yönetimi için idealdir. Kurulumu daha karmaşıktır.
Zustand Hafif ve çok hızlıdır. Harici kütüphane bağımlılığı ekler.

Sıkça Sorulan Sorular

Context API kullanmak uygulamayı yavaşlatır mı?

Küçük ve orta ölçekli uygulamalarda tema yönetimi gibi basit işlemler için Context API son derece performanslıdır. Ancak binlerce bileşenin aynı anda güncellendiği devasa yapılarda performans optimizasyonu gerekebilir.

Neden localStorage kullanmalıyım?

Kullanıcı deneyimi açısından, kullanıcının seçtiği temanın tarayıcıyı kapatsa bile hatırlanması profesyonel bir standarttır.

Farklı temalar (örneğin mavi, yeşil) ekleyebilir miyim?

Evet, useState içindeki değeri bir dizi veya nesne yaparak kolayca genişletebilirsiniz.

TypeScript ile kullanabilir miyim?

Kesinlikle. createContext(undefined) şeklinde tanımlayarak tip güvenliğini sağlayabilirsiniz.

Context API yerine neden kütüphane kullanmayayım?

Eğer uygulamanız sadece basit bir tema değiştirici içeriyorsa, ekstra bir kütüphane yüklemek "bundle" boyutunuzu gereksiz artırır. Context API, React'in kendi sunduğu en doğal çözümdür.

Yasal Uyarı: Bu rehberdeki kod örnekleri eğitim amaçlıdır. Üretim ortamında (production) kullanırken CSS sınıflarınızın ve state yönetiminizin uygulamanızın genel mimarisiyle uyumlu olduğundan emin olun. Yazılım güvenliği sorumluluğu geliştiriciye aittir.

İleri Seviye İpuçları: Sistem Temasını Otomatik Algılama

Kullanıcı deneyimini bir üst seviyeye taşımak için, uygulamanızın kullanıcının işletim sistemi (OS) tercihine göre otomatik olarak "koyu" veya "açık" moda geçmesini sağlayabilirsiniz. Bu, window.matchMedia API'si ile oldukça kolay bir şekilde gerçekleştirilebilir.

Aşağıdaki kod bloğu, ThemeContext içerisinde sistem temasını nasıl dinleyebileceğinizi göstermektedir:

useEffect(() => {
  const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
  
  const handleChange = (e) => {
    const newTheme = e.matches ? 'dark' : 'light';
    setTheme(newTheme);
  };

  mediaQuery.addEventListener('change', handleChange);
  
  return () => mediaQuery.removeEventListener('change', handleChange);
}, []);

Bu yaklaşım, kullanıcının manuel bir seçim yapmadığı durumlarda uygulamanızın modern ve uyumlu görünmesini sağlar. useEffect içerisinde kullanılan removeEventListener temizleme fonksiyonu, bellek sızıntılarını (memory leaks) önlemek için kritik öneme sahiptir.

Tema Değişiminde Performans Optimizasyonu

Context API kullanırken, Provider bileşeninin value değerine doğrudan bir obje geçirmek, her render döngüsünde yeni bir referans oluşturulmasına neden olabilir. Bu durum, Context'i tüketen tüm bileşenlerin gereksiz yere yeniden render edilmesine yol açar. Performansı artırmak için useMemo kancasını kullanmalısınız.

Aşağıdaki yapı, performans kaybını önlemek için standart bir yaklaşımdır:

const contextValue = useMemo(() => ({
  theme,
  toggleTheme
}), [theme]);

return (
  
    {children}
  
);

Bu yöntemle, sadece theme değeri değiştiğinde Context güncellenir. Ayrıca, büyük ölçekli uygulamalarda Context'i daha küçük parçalara bölmek (örneğin; tema verisi için ayrı, kullanıcı tercihleri için ayrı Context'ler) render performansını optimize etmenize yardımcı olur.

Hata Ayıklama (Debugging) İpuçları

  • React DevTools: Tarayıcınızdaki React DevTools eklentisini kullanarak, Provider bileşeninin altındaki değerlerin anlık olarak nasıl değiştiğini "Components" sekmesinden izleyin.
  • Console Logları: Tema değiştiğinde Provider'ın kaç kez render edildiğini görmek için console.log('Provider Rendered') satırını ekleyerek gereksiz güncellemeleri tespit edebilirsiniz.
  • CSS Değişkenleri: Eğer tema geçişlerinde titreme (flicker) yaşıyorsanız, CSS değişkenlerini :root seviyesinde tanımladığınızdan ve body etiketine sınıf atama işlemini DOM'un en üst seviyesinde yaptığınızdan emin olun.
Not: Çok büyük ölçekli ve karmaşık tema yapılarına (örneğin 50+ farklı renk değişkeni) sahip uygulamalarda, Context API yerine Styled-components veya Tailwind CSS'in yerleşik tema özelliklerini kullanmak, bakım maliyetini düşürebilir.

Sonuç

React ile Context API kullanarak global bir tema değiştirici kurmak, hem öğrenmesi kolay hem de oldukça işlevsel bir yöntemdir. Bu rehberde; context oluşturma, sağlayıcıyı yapılandırma, bileşenler arası veri aktarımı ve localStorage ile kalıcı hale getirme adımlarını tamamladık. Bir sonraki adım olarak, bu yapıya "Sistem Temasını Algıla" (OS Theme Detection) özelliğini ekleyerek kullanıcının tarayıcı ayarlarını otomatik okuyan bir yapı geliştirmeyi deneyebilirsiniz.

Bu yazıya tepkinizi paylaşın:
Deniz Aydın

On yıllık içerik üretimi deneyimiyle karmaşık süreçleri herkesin anlayabileceği basit adımlara dönüştürüyorum. Pratik ev çözümleri ve hayatı kolaylaştıran teknikler konusunda uzmanım.

Yorumlar (0)

Yorum Yaz