State Bileşenini Yönetmeyi Sağlayan Yeni Bir Javascript Kütüphanesi - REDUX

3 ay önce , Okuma süresi 4 dakika.

Her geçen gün karşımıza yeni teknolojiler, yeni diller, yeni frameworkler çıkıyor. Özellikle front-end development yapan birisiyseniz artık çıkan frameworkleri, kütüphaneleri takip etme şansınız pek kalmadı.
State Bileşenini Yönetmeyi Sağlayan Yeni Bir Javascript Kütüphanesi  - REDUX

Daha birisi çıktı şunu öğreneyim dediğiniz noktada yeni bir şey çıkıyor. Hangisini öğreneceğim telaşı içinde, kendimizi her şeyi yarım yarım öğrenmiş buluyoruz. Çıkan teknoloji iyi, güzel, şık duruyor ancak eskilerde aynı işi yapmıyor mu? Genellikle evet, aynı işi yapıyor. Belki bu yeni çıkan biraz daha havalı yapıyor ancak yine de aynı şeyi yapıyor.

Redux, bir javascript kütüphanesidir. Redux, React’ın olmazsa olmazı veya bir parçası değildir. Dan Abramov tarafından geliştirilmiş bir kütüphanedir. Asıl görev tanımı ise, Javascript uygulamalarında state bileşenini yönetmeyi sağlayan javascript kütüphanesidir. Redux ile React’ın birlikte anılmasının sebebi, birlikte popüler olmaları ve entegre bir şekilde çok iyi çalışıyor olmalarıdır. Redux, literatürde Application State Management yani Uygulama Durum Yönetici olarak geçmektedir. React uygulamaları geliştirirken, state bileşenleri üzerinden geliştirme yapılmaktadır. Redux denilen yapı ise bu state bileşenlerini yönetmemizi sağlayan kütüphanedir.

Redux aslına bakarsanız bir state container’dır. Eğer react dünyasına aşina değilseniz “state” tanımının ne amaçla kullanıldığını bilmiyor olabilirsiniz.

React ile geliştirilecek sistem component’lerden oluşur. Her component kendi içinde kullanacağı veriyi ya props üzerinden ya da state üzerinden alarak kullanır. Props read-only modda çalışır, sadece üst component’in verdiği bilgiyi alt component’e taşır, state ise component içindeki durum bilgisini saklar. Örneğin ekran üzerinde herhangi bir checkbox’ı tıkladınız. Tıkladığınız bilgisini bir state’e bağlarsanız, state bilgisi her checkbox seçiminizde değişecektir. Dolayısı ile state, component içinde herhangi bir şey üzerine durum bilgisi tutan, read-only olmayan bir tanımlamadır.

React’ın yapımcısı facebook’lu mühendisler react’ı çıkardıklarında flux yapısını tanıtmışlar. Flux yapısını kullanan geliştiriciler flux’dan daha iyisi redux olacak diyip, redux’ı hayata geçirmişler. Dolayısı ile artık hayatımızda redux state container’ı var.

React ile uygulama geliştirirken bileşenler (componentler) ve bu bileşenleri oluşturan stateler bulunmaktadır.  Uygulamalarımızı geliştirdikçe bileşenlerimiz artmakta, haliyle state yapılarımız da artmaktadır. Bu durumda bileşenleri yönetmek oldukça zorlaşmaktadır. İşte bu noktada Redux kullanmak tüm bu karmaşanın arasından kurtulmamıza olanak sağlamaktadır.

Redux kütüphanesini biraz daha nesnel anlamaya çalışırsak; yukarıda gördüğünüz resimde Redux kullanarak ve Redux kullanmadan bir uygulama bileşen şeması gösterilmiştir.

Redux’ın Üç Silahşörlerini Tanıyalım: Action, Reducer ve Store

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.

Birlikte bu yapıları örnekte inceleyelim.

Örnek tek bir html sayfasından ve içerisine gömülü olan script'ten oluşuyor. Elbette gerçek bir uygulamada tüm yapıları birbirinden ayırmanız ve mümkünse de ES2015, WebPack ve Babel kullanmanız gerekir. Ancak Vanilla JS, öğrenme sürecinde daha basit olduğu için daha uygun.

Action (4 tane)

Action creator (4 tane)

Reducer (2 tane)

Initial State

Root Reducer

Dispatch Action

gibi REDUX'ın temel bileşenlerini olabilecek en basit şekilde anlatmaya çalıştım. redux-thunk örneği ile birleştirilmesini ise gelecek bir zamanda yüklemeye çalışacağım.

Örneğe direk olarak aşağıdaki adresten ulaşabilirsiniz:

https://s3.us-east-2.amazonaws.com/cuneyt-aliustaoglu/blog.tr/ReduxBasitveKompleOrnek/index.html

En basit Redux örneği

Örneğimizde 2 temel nesne var.

  • Metin kutusu
  • Düğme

Metin kutusuna ait biri metin içeriği diğeri ise rengi olmak üzere 2 action'ımız var. Düğme için ise düğme text değeri ve düğmenin aktifliği olmak üzere yine 2 tane action'umuz var. Bu örnekteki 2 nesne yerine 100 nesneniz de olsa yapı aynı kalacak.
 

Action creator
Metin kutusu ve düğmenin state'ini değiştirecek action'lar

// Metin ile ilgili action'lar
        var actionMetinIcerik = function(icerik) {
            return {
                type: "METIN.ICERIK",
                icerik: icerik
            }
        }
        var actionMetinRenk = function(renk) {
            return {
                type: "METIN.RENK",
                renk: renk
            }
        }

        // Düğme ile ilgili action'lar
        var actionDugmeDeger = function(deger) {
            return {
                type: "DUGME.DEGER",
                deger: deger
            }
        }
        var actionDugmeAktiflik = function(aktiflik) {
            return {
                type: "DUGME.AKTIFLIK",
                aktiflik: aktiflik
            }
        }
}

Reducer

// Metin ile ilgili reducer (yalnızca metinle ilgili action'larla ilgilenir)
        var reducerMetin = function (state, action){
            if (typeof state === 'undefined') {
                return null;
            }
            switch(action.type) {
                case "METIN.ICERIK":
                    return Object.assign({}, state, { icerik : action.icerik });
                case "METIN.RENK":
                    return Object.assign({}, state, { renk : action.renk });
                default:
                    return state;
            }
        }
        // Düğme ile ilgili reducer (yalnızca düğme ile ilgili action'larla ilgilenir)
        var reducerDugme = function (state, action){
            if (typeof state === 'undefined') {
                return null;
            }
            switch(action.type) {
                case "DUGME.DEGER":
                    return Object.assign({}, state, { deger : action.deger });
                case "DUGME.AKTIFLIK":
                    return Object.assign({}, state, { aktiflik : action.aktiflik });
                default:
                    return state;
            }
        }

Initial State

var initialState = {
            reducerMetin: {
                icerik: "Metin",
                renk: "White"
            },
            reducerDugme: {
                deger: "Dugme",
                aktiflik: true
            }
        }

Root reducer

// Bütün reducerları birleştir (her yeni yapı için yeni reduclerlar oluşturun)
        var rootReducer = Redux.combineReducers({
            reducerMetin: reducerMetin,
            reducerDugme: reducerDugme
        });

Create Store

// rootReducer'ın olduğu store'umuzu oluşturalım
        var store = Redux.createStore(rootReducer, initialState);

Listeners

 // Listeners
        var renderMetin = function(){
            $('#txtMetin').val(store.getState().reducerMetin.icerik);
            $("#txtMetin").css('background-color', store.getState().reducerMetin.renk);
        }

        var renderDugme = function(){
            $('#btnDugme').val(store.getState().reducerDugme.deger);
            $('#btnDugme').prop('disabled', !store.getState().reducerDugme.aktiflik);
        }

Subscribers

// Listeners için Subscribers
        store.subscribe(renderMetin);
        store.subscribe(renderDugme);

Klasik JS Fonksiyonlarımız

  // Klasik HTML/JS fonksiyonlarımız
        var btnMetinIcerikOnClick = function(){
            var act = actionMetinIcerik($("#txtMetinIcerik").val());
            store.dispatch(act);
        }

        var btnMetinRenkOnClick = function(){
            var act = actionMetinRenk($("#txtMetinRenk").val());
            store.dispatch(act);
        }

        var btnDugmeDegerOnClick = function(){
            var act = actionDugmeDeger($("#txtDugmeDeger").val());
            store.dispatch(act);
        }

        var btnDugmeAktiflikOnClick = function(){
            var act = actionDugmeAktiflik($("#chkDugmeAktiflik").prop('checked'));
            store.dispatch(act);
        }

Oldukça basit ve sade bir dizayn olduğu için kod kendisini zaten anlatıyor.

Örnek kaynağı :https://cuneyt.aliustaoglu.biz/tr/reduxa-giris-basit-fakat-komple-bir-ornek/ 

#javascript