React / React Native Context Kullanımı (Redux Yerine Context)

React Native ile yazdığımız mobil uygulamalarda ihtiyaç duyduğumuz temel özelliklerden bir tanesi sayfalar ya da bileşenler arası parametreler gönderme ve bunu alıp kullanma.

Problem 1 – Birden Fazla Sayfa ya da Bileşende Aynı Değerlerin Kullanılması

Mobil uygulamamızda birden fazla sayfa ya da bileşende aynı değerleri kullanmak durumunda kalabiliriz. Mesela kullanıcı bilgileri, cookie bilgileri gibi. Bu ve buna benzer gereksinimlerde her sayfaya ya da bileşene parametre geçmek hem külfetli olmakta hem kod karmaşıklığına yol açmakta hem de olası hatalara sebep olmaktadır.

Problem 2 – Kullanılan Değerin Güncellenmesi ve Kullanıldığı Sayfa ya da Bileşenlere Yansıması

Kullandığımız bir ya da birden fazla değerin güncellenmesi gerekebilmektedir. Bu değerlerin güncellenmesi ve tüm sayfa ya da bileşenlere de uygulanması durumunda ortalık çok karışmaktadır. Yani çarşı karışıyor.

Çözüm 1 – Redux

Yukarı bahsedilen 2 problemin çözümü için kullanılan yöntem Redux kullanımı idi. Redux kullanarak bu problemleri çözebiliyoruz.

Çözüm 2 – Context

Bu problemlerin diğer çözümü ise context kullanımı. Context kullanarak istediğimiz sayfalara ya da bileşenlere birden fazla parametre gönderebilir ve bu parametreleri tek bir hamle ile güncelleyebilir ve bunların bütün sayfalarda işlenmesi sağlayabiliriz.

Context ile Redux kullanmak zorunda kalmayız ve böylelikle yeni bir kütüphane kurulumu ile de uğraşmak durumu oluşmamış olur.

Context Kullanımı

Context, adından da anlaşılacağı üzere sayfaları kapsayan, onları içinde sarmalayan bir yapıdır.

Kod düzeni ve anlaşılabilirliği açısından her bileşeni ve fonksiyonu ayrı ayrı sayfalarda yazacağız.

Context Oluşturma

Öncelikle bir context oluşturalım ve bu context neleri tutacak ve paylaşacak onları belirleyelim.

Örnek mobil uygulamamızda kullanıcı login olduğunda dönen cevapta kullanıcının adı, soyadı, mail adresi ve doğum tarihi değerleri dönsün. Yine bunlarla birlikte uygulama içerisinde api isteklerinde kullanmamız gereken cookie değeri dönsün. Ayrıca uygulama içerisinde ön yüzde kullanmamız gerekebilecek olan cihaz boyut değerlerini de context e bağlayarak her seferinde bu değerleri hesaplatmaktan da kurtulmuş olalım.

Context imizi createContext fonksiyonu ile oluşturmaktayız ve context e bağlı değerleri de bu fonksiyona parametre vererek belirtmekteyiz.

Context te yer alan üstte belirtilen değerlerin güncellenmesi için iki tane fonksiyon tanımlayalım. Bunlardan bir tanesi kullanıcı bilgilerini güncellemede, diğeri ise cookie bilgisini güncellemede kullanılsın.

Context oluşturduktan sonra bunu kullanmaya geldi sıra. Context in iki objesi vardır. Provider ve Consumer. Context Provider, sayfaları besleyen context katmanıdır. Context Consumer ise sayfalarda context değerlerini kullanmamızı ve bu değerleri güncelleyebilmemize olanak tanıyan katmandır.

Alttaki kod parçacığında yukarıda anlatılanlar gösterilmektedir.

import React from 'react';
import {Dimensions} from 'react-native';

export const auth = {
  email: '',
  name: '',
  surname: '',
  date: '',
};

export const cookie = null;

export const width = Dimensions.get('window').height;

export const height = Dimensions.get('window').height;

export const AuthContext = React.createContext({
  auth,
  cookie,
  width,
  height,
  toggleAuth: () => {},
  toggleCookie: () => {},
});

export const AuthProvider = AuthContext.Provider;
export const AuthConsumer = AuthContext.Consumer;

Context yapısını oluşturduk. Şimdi sayfalarımızı Context Provider yani bizdeki AuthProvider içerisine almaya geldi.

Öncelikle sayfalarımız için stack leri oluşturuyoruz. Daha sonra Provider a vereceğimiz değerleri bir state te tutarak value olarak veriyoruz.

constructor(props) {
    super(props);

    this.toggleAuth = user => {
      this.setState(state => ({
        auth: user,
      }));
    };

    this.toggleCookie = token => {
      this.setState(state => ({
        cookie: token,
      }));
    };

    this.state = {
      auth: null,
      cookie: null,
      height: Dimensions.get('window').height,
      width: Dimensions.get('window').width,
      toggleAuth: this.toggleAuth,
      toggleCookie: this.toggleCookie,
    };
  }

State yapımız da oluştuğuna göre Provider ı oluşturup uygulamayı başlatabiliriz.

render() {
    return (
      <AuthProvider value={this.state}>
        <NavigationContainer>
          <Stack.Navigator
            screenOptions={{
              headerStyle: {
                height: 0,
              },
              gestureEnabled: false,
            }}>
            <Stack.Screen name="AuthStack" component={AuthStack} />
            <Stack.Screen name="MenuStack" component={MenuStack} />
          </Stack.Navigator>
        </NavigationContainer>
      </AuthProvider>
    );
  }

Yapılan işlemler sonrası Provider ın içinde yer alan bütün sayfalar context değerlerine erişebilir ve bu değerleri güncelleyebilir.

Context değerlerine erişebilme ve güncelleyebilme işlemi ise Consumer katmanındadır. Bizim Consumer ımız AuthConsumer kullanılacaktır. Bunun için render içerisinde yer alan ön yüz kodumuzu AuthConsumer ile sarmalıyoruz. Context değerlerini de içerisinde tanımlayabiliyoruz.

<AuthConsumer>
        {({auth, height, toggleAuth, toggleCookie}) => (
          <View>
            ...
          </View>
        )}
</AuthConsumer>

Yukarıda gösterildiği gibi auth objesinin içerisinde kullanıcı bilgileri bulunuyor ve bu değerlere auth.name, auth.surname şeklinde erişebilmekteyiz.

Eğer auth ya da cookie bilgisinde değişiklik yapılacaksa yine context te yer alan fonksiyonlar ile yapılabilmektedir. Eğer auth değeri değişecek ise toggleAuth(newAuth) şeklinde güncelleme yapabiliriz.

Context değerlerini render içinde değil de sayfada yer alan diğer fonksiyonlar içinde kullanabilmek için constructor ın üstünde context imizi tanımlıyoruz. Daha sonra istediğimiz herhangi bir fonksiyonda context değerlerini kullanabiliriz.

static contextType = AuthContext;
....
anyFunction() {
const kullanıcıBilgileri = this.context.auth;
}

React ve React Native ile yazılan web ya da mobil uygulamalarda Context kullanımı bu şekilde olmaktadır. Bu yazıda React Context kullanımı, yapısı ve özellikleri anlatılmıştır. Yazıda sınıf yapısı üzerinden gidilmiştir. Bir sonraki yazıda React Context Hooks anlatılacaktır. Yani sınıf yapısını kullanmadan kancalama yöntemi ile Context nasıl kullanılır ona değineceğiz.

Teşekkürler.