Redux Nedir, Nasıl Kullanılır? #Bölüm-1

Redux, Dan Abramov ve Andrew Clark tarafından geliştirilen bir yönetim kütüphanesi. Redux’la birlikte uygulamanız dahilinde hem veri yönetimini yapabilir hem de ui tarafını yönetebilirsiniz. Böylelikle Redux kullanımıyla birlikte, zamanla uygulama üzerindeki hakimiyetinizi rahatlıkla koruyabilirken, kapsamı gittikçe büyüyen uygulamaları da çok daha rahat yönetmeniz mümkün olabilir.

Redux’la kullanacağımız bazı nesneler ya da kavramlar var. Öncelikle onlardan kısaca bahsetmek gerekebilir. Mantığını anlayabilmemiz için ihtiyacımız olan üç ana kavram; “store”, “reducer” ve “action” diyebiliriz.

store: Redux kütüphanesiyle birlikte yaratacağımız verilerin tutulacağı alan diyebiliriz. Uygulamamızda tek bir adet “store”umuz olacak ve state’lerimizi bu store’un içinde depolayacağız.

reducer: Action’dan gelen verileri süzgeçleyip store’da belirtilen veriyi güncellememizi sağlayan bir araç.

action: Reducer’lara ulaşarak onları tetikleyen, store’daki güncellemesi gereken veriyi yollan bir araç. Neyi güncellemesi gerektiğini adlandırırken “type” ile belirtmemiz gerekirken, değiştirmesi gereken veriyi payload’larla taşır.

Örnek Kullanım:

React ve redux’ı kullanabilmeniz için birçok paket söz konusu. Biz burada daha pratik olduğu için create-react-app paketini kullanacağız. Github’da arayarak, kendinize daha uygun olduğunu düşündüğünüz bir çok boilerplate vb. yapılar bulabilir ya da doğrudan parcel bundler gibi daha pratik çözümler de tercih edebilirsiniz.

Terminal üzerinden çalışmak istediğiniz proje dizinine gidip uygulama dosyalarımızı oluşturalım.

// özellikle osx kullanıcıları için doğrudan user klasörü altında projects gibi bir dizin açıp içinde çalışmak mantıklı olabilir
npx create-react-app redux-medium
// Komutuyla uygulama dosyalarınızı oluşturuyorsunuz. Burada dikkat etmeniz gereken nokta; sonda belirttiğiniz "redux-medium" oluşturulacak klasör adıdır. İstediğiniz ismi verebilirsiniz.

Dosyaların kopyalama işlemi bittikten sonra, uygulama dizinimizin içine girelim.

cd redux-medium
// Uygulama dizininde iken terminalden yarn* start yazdığınızda uygulamanız 3000 portunda çalışmaya başlayacaktır.
Ben paket yöneticisi olarak yarn kullanıyorum. Siz npm run start yazarak da aynı sonuca ulaşabilirsiniz.

Şimdi uygulamamızın içerisine redux ve react-redux paketlerini eklememiz gerekiyor.

yarn add redux react-redux

*react-redux paketini belki doğrudan bu anlatımda kullanmayacağız. Belirtmek istedim ki içinden çekeceğimiz nesnelerle bir sonraki anlatımlarda, component’lar içerisinde yaratılan store verilerine nasıl erişeceğimizi göstereceğiz.

*sublime — DA UI

Bu anlatımda redux’un mantığının anlaşılması için index.js içerisinde, yani tek bir dosya üzerinde çalışacağız. İleriki anlatımlarda daha farklı bir dizin yapısı tercih ederek, yazdığımız kodların bir kısmını ayıracağız.

Öncelikle index.js içerisindeyken store yaratabilmemizi sağlayacak createStore nesnesini dosyamıza dahil etmemiz gerekiyor. Bunun içinde daha önce yüklediğimiz redux paketini kullanacağız.

 import { createStore } from 'redux';

createStore’u uygulamaya dahil ettikten sonra yaratmamız gereken bir reducer olacaktır. Örnek olarak bir foodReducer adında bir fonksiyon oluşturacağız.

function foodReducer(state = 'elma', action) {
return state;
}
// Burada state = 'elma' şeklinde kullanarak reducer'imizin store'a göndereceği default değer string ve elma olarak belirliyoruz. Bu daha sonra başka başka component'larda kullanabileceğimiz bir veri olarak store'umuz içerisine kaydolacaktır.

Reducer’i da yarattıktan sonra, store objemizi oluşturmamız gerekiyor.

const store = createStore(foodReducer);

Şu an foodReducer’in state’ini kendi içerisinde döndüren bir store objesi yaratmış bulunmaktayız. Bunu görebilmemiz için;

console.log(store.getState());

şeklinde bir kullanım yeterli olacaktır. Tarayıcıya gittiğimizde console’da “elma” yazdığını göreceğiz. Şu an için tek bir reducer’i olan basit bir redux dizaynını oluşturmuş bulunmaktayız.

Şimdiye kadar yazdıklarımız:

// index.js görünümü
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import { createStore } from 'redux';
function foodReducer(state = 'elma', action) {
return state;
}
const store = createStore(foodReducer);
console.log(store.getState());
ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();

Bu aşamada var olan reducer’a action ile müdahale ederek store içindeki state’leri action’den gelen payload ile güncelleyeceğiz.

Önce action oluşturuyoruz.

const updateFoodDatas = {
type: "UPDATE_FOOD",
payload: "armut"
}

Sonrasında store ile birlikte dispatch metotuyla oluşturduğumuz action’u yakaladığımızda, eğer action type’i belirttiğimiz tipse reducer’daki state’i güncelle komutunu vermemiz gerekiyor. Bunu da reducer’a basit bir switch yapısı ekleyerek yapacağız.

function foodReducer(state = 'elma', action) {
switch (action.type) {
case "UPDATE_FOOD":
return action.payload;
default:
return state;
}
}

Yukarıda eğer ki action.type UPDATE_FOOD ise action.payload’i döndür, değilse varolan state’i döndür diyoruz. Son olarak yapmamız gereken store’un içindeki dispatch metotu ile action’u çalıştırmak.

store.dispatch(updateFoodDatas);

Farkı görebilmek adına, action’dan önce ve sonra olmak üzere “console.log(state.getState());” komutunu ekleyebiliriz.

Console’a baktığımızda “elma” olan değerimiz action kullanımından sonra “armut” olarak güncellenececktir.

Kodumuzun son halinin çıktısı:

Mantığını anlatabilmek adına, ilk bölümü burada sonlandırıyoruz. Bir sonraki yazıda birden fazla reducer kullanımı ve, parçalanmış dizinlerde action, reducer dağılımı ve farklı component’lar içerisindeyken store’u nasıl güncelleyebileceğimizi anlatmaya çalışacağız.

Anlatımı gözden geçirerek gerekli yerlerde düzeltmelerde bulunan Tahsin Cem Yılmaz’a çok teşekkürler.