React Native, mobil uygulama geliştirmek için popüler bir JavaScript çerçevesidir. Ancak, büyük ve karmaşık uygulamalarda durum yönetimi önemli bir sorundur. Bu sorunu çözmek için Redux, Redux Thunk ve Redux Saga gibi araçlar kullanılır. Bu yazıda, bu teknolojilerin nasıl kullanılacağını ve farklarını inceleyeceğiz.

Redux Nedir?

Redux, React ve React Native uygulamalarındaki durumu yönetmek için kullanılan bir State Management (durum yönetim) kütüphanesidir. Redux, uygulama durumunu tek bir alanda (store) tutar ve bu alandaki durum değişikliklerini bir dizi kurala göre yönetir. Böylece storemizdeki tüm stateleri uygulamamızdaki herhangi bir ekrandan kolayca yönetebiliriz. Bu da bize uygulamamızın daha efektif ve daha performanslı çalışmasını sağlar.

Redux’in temel kavramları şunlardır:

Store:
Uygulamamızdaki statelerin tutulduğu yerdir (Ör: app_path/redux/store.js). Store, başlangıçta bir başlangıç durumu (initial state) ve uygulama durumunu değiştiren bir reducer içerir. Storede bulunan bu stateler dispatch() fonksiyonu ile daha önceden belirlediğimiz actionlara göre güncellenir.

Uygulamamızın ana dizininde redux adında bir klasör olduğunu var sayarak aşağıdaki gibi bir store tanımlayabiliriz.

import { createStore } from 'redux'; //createStore fonksiyonunu redux kütüphanesinden çağırıyoruz.
import Reducer from 'redux/reducers'; //Yazının devamında oluşturacağımız Reducer dosyasını çağırıyoruz
const store = createStore(Reducer); //Son olarak createStore() fonksiyonunu kullanarak ve üst satırda import ettiğimiz Reducer'imizi parametre olarak göndererek store değişkenimizi oluşturuyoruz

Action:
Storede tuttuğumuz stateleri değiştirmek için kullanılan bir nesnedir ve genellikle bir tür (type) ve gerekirse bir payload (veri) içerir. Bu actionlar dispatch() fonksiyonuyla storemize yönlendirilir.

Aşağıda addTodo adında oluşturulmuş bir action ve bu action kullanılarak storedeki bir stateyi nasıl güncelleyebileceğimize ait bir örnek bulunuyor.

// addTodo adında bir Action Tanımla
 const addTodo = (text) => {
   return {
     type: 'ADD_TODO',
     payload: {
       text,
       completed: false
     }
   };
 };
 // Actionu kullanarak storedeki stateyi güncelle
 store.dispatch(addTodo('Yeni görev ekle'));

Reducer:
Stateleri bir eyleme göre güncelleyen fonksiyondur. Her bir reducer, belirli bir parça durumu yönetir. Reducerlar parametre olarak state ve action alır, ardından yeni bir state döndürür.

Aşağıda örnek bir reducer bulunmaktadır.

const todosReducer = (state = [], action) => {
 switch (action.type) { //Action.type'ye göre bir switch case döngüsü oluşturuyoruz
  case 'ADD_TODO': 
    //Eğer action type 'ADD_TODO' ise payloaddan gelen veriyi mevcut stateye dahil edip storedeki stateyi güncelle
    return [...state, action.payload];
  default:
    //Eğer değilse mevcut stateyi döndür
    return state;
 }
};

Redux Thunk Nedir?

Redux Thunk, Redux için bir middleware’dir ve asenkron eylemleri yönetmeye yardımcı olur. Eğer uygulamanızda asenkron işlemler varsa (API çağrıları gibi), Redux Thunk kullanmak işleri kolaylaştırabilir.

Thunk bir fonksiyondur ve döndürdüğü değer de bir fonksiyondur ve actionlar yerine fonksiyonları (thunk’ları) kullanmanıza izin verir. Bu sayede, asenkron işlemleri yönetmek daha kolay hale gelir.

Redux için bir örnek:

const fetchData = () => {
   return (dispatch) => {
     dispatch({ type: 'FETCH_DATA_REQUEST' });
     
     apiCall()
     .then(data => dispatch({ type: 'FETCH_DATA_SUCCESS', payload: data }))
     .catch(error => dispatch({ type: 'FETCH_DATA_FAILURE', payload: error }));
   };
 };

Redux Saga Nedir?

Redux Saga, Redux için bir middleware’dir ve asenkron işlemleri daha etkili bir şekilde yönetmeye olanak tanır. Redux Saga, Generator fonksiyonları kullanarak eylemleri ve yan etkileri kontrol etmenizi sağlar.

Redux Saga’nın temel özellikleri şunlardır:

  • Generator Fonksiyonları: Asenkron işlemleri daha okunabilir ve yönetilebilir hale getirir.
  • Effect’ler: Redux Saga, çeşitli etkileşimler için özel “effect”ler sunar (örneğin, API çağrıları, gecikmeler, vs.).
  • Middleware: Redux Saga, Redux middleware’i olarak entegre edilir ve uygulama durumunu yönetir.

Redux Saga kullanım örneği:

function* watchFetchData() {
   yield takeLatest('FETCH_DATA_REQUEST', fetchData);
}

function* fetchData(action) {
  try {
     const data = yield call(apiCall);
     yield put({ type: 'FETCH_DATA_SUCCESS', payload: data });
  } catch (error) {
     yield put({ type: 'FETCH_DATA_FAILURE', payload: error });
  }
}

Redux Thunk vs. Redux Saga

Redux Thunk ve Redux Saga, her ikisi de asenkron işlemleri yönetmek için kullanılır, ancak farklı yaklaşımları vardır. Redux Thunk daha basit ve hafifken, Redux Saga daha güçlü ve karmaşık uygulamalara daha uygun olabilir.

Redux Thunk ne zaman tercih edilmelidir:

  • Daha basit uygulamalarda.
  • Daha hızlı öğrenilmek istenildiğinde.

Redux Saga ne zaman tercih edilmelidir:

  • Büyük ve karmaşık uygulamalarda.
  • Gelişmiş kontrol ve özelleştirme ihtiyacı olduğunda.

Hangi yaklaşımı kullanılacağınız size ve projenin gereksinimlerine göre değişebilir. Yukarıdaki tercih durumlarına göz önünde bulundurarak hangi middlewareyi kullanacağınıza kolayca karar verebilirsiniz 🙂

Bu yazımda, Redux, Redux Thunk ve Redux Saga’ hakkında bildiklerimi elimden geldiğince anlatmaya çalıştım. Umarım faydalı olmuştur. Eksiklerim varsa ya da bildiğiniz daha farklı bir yöntem varsa e-posta adresimden veya iletişim sayfamdan ulaşabilirsiniz. İyi kodlamalar 🙂