Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Redux ile Önyüz Uygulamalarında Veri Yönetimi

Redux ile Önyüz Uygulamalarında Veri Yönetimi

Ziraat Teknoloji'de her hafta düzenlenen Ziraat TechTalks kapsamında 16 Kasım 2017 tarihinde yapılan Redux kütüphanesi hakkındaki konuşması.

Bu konuşmada genelde React kullanan uygulamalarda veri katmanında yardım sağlayan Redux kütüphanesine bir genel giriş yapıldı.

Video: https://youtu.be/VQB3e1f96lE

Üstün Özgür

November 16, 2017
Tweet

More Decks by Üstün Özgür

Other Decks in Programming

Transcript

  1. Redux ile Veri
    Yönetimi
    Üstün Özgür

    [email protected]

    twitter.com/UstunOzgur

    Üstün Özgür Yazılım

    View full-size slide

  2. State Container
    Veri Konteyneri - Deposu

    View full-size slide

  3. Veri (Model) Görüntü
    Kontrolcü
    MVC
    Model - View - Controller
    Model - Görüntü - Kontrolcü
    React, taslaklar...

    View full-size slide

  4. Model ve Veri
    • Nesne Yönelimli Programlama

    • Temel Veri (Model) Soyutlaması?

    • Nesneler

    • Nesnelerin içindeki veri alınır

    • getter metodları: hesap.getBakiye()

    • setter metodları: hesap.setBakiye(100)

    • Aynı zamanda set metodunda nesne başka bir nesneye haber
    verebilir

    • Örneğin görüntü katmanına

    View full-size slide

  5. MVC'daki Model Katmanı
    için Minimum Neler Gerekli?
    • Interface: Tek bir set, tek bir get metodu

    • getState(): Modeldeki veriyi almak için:

    • MEGA getter

    • dispatch(action): Modele veri değişikliği emri göndermek için

    • MEGA setter

    • subscribe(): Modeldeki veri değişikliklerinden haberdar
    olmak için

    View full-size slide

  6. Model / Veri Ambarı / Depo /
    Repo / Dükkan / Store / Database!
    Store
    - getState()
    - dispatch(action)
    - subscribe(listener)

    View full-size slide

  7. class Store {
    _state = {};
    getState() {
    return state;
    }
    dispatch(action) { // Dispatch: Haber Gonder
    this.state = this._veriyiDegistir(this._state, action);
    this.abonelereHaberVer();
    }
    _aboneler = [];
    subscribe(aboneFonksiyonu) {
    this._aboneler.push(aboneFonksiyonu);
    }
    _abonelereHaberVer() {
    this.aboneler.forEach(aboneFonksiyonu => aboneFonksiyonu());
    }
    _veriyiDegistir(eskiState, action) {
    /// hesaplamalar.... // Sadece burasi ozellestirilecek (uzerine yaz!)
    return yeniState;
    }
    }

    View full-size slide

  8. class TodoStore extends Store {
    _state = { todos: [], yeniTodo: "" };
    _veriyiDegistir(state, action) {
    let yeniState;
    switch (action.type) {
    case "SET_YENI_TODO":
    yeniState = { todos: eskiState.todos, yeniTodo: action.payload };
    case "INSERT_TODO":
    yeniState = {
    todos: [...state.todos, state.yeniTodo],
    yeniTodo: ""
    };
    break;
    default:
    yeniState = state;
    }
    return yeniState;
    }
    }

    View full-size slide

  9. Örnek
    • depo.getState()

    • aboneFonksiyonu = () => log("Depo degisti")

    • depo.subscribe(aboneFonksiyonu)

    • depo.dispatch({type: 'SET_TODO'})

    • depo.getState()

    View full-size slide

  10. veriyiDegistir
    (state, action) => state
    • veriyiDegistir metodu

    • Iki veri girdi, bir tane cikti

    • Sayi azaldi: Ingilizce reduce

    • Bu nedene reducer denilmis redux'ta

    View full-size slide

  11. reducer
    • Reducer, inheritance yerine reducer alan createStore
    adinda bir yardimci metod sagliyor

    • Reducer, ilk basta constructor, sonrasinda setter gorevi
    goruyor.

    • Onun disinda API gosterdigimizle tamamen ayni

    View full-size slide

  12. reducer
    veriDegistirmeFonksiyonu = (state=defaultState, action) => {
    switch (action.type) {
    ...
    }
    • defaultState: constructor gibi düşünün, kalanını da MEGA setter gibi

    • depo = createStore(veriDegistirmeFonksiyonu)

    • depo.getState()

    • depo.subscribe(aboneFonksiyonu)

    • depo.dispatch({type: 'SET_TODO'})

    View full-size slide

  13. Kompozisyon
    • Bir nesnenin birden çok nesneden oluşması

    • Avantajı: İşleri alt parçalara böl ve başkalarına havale et

    class Araba {
    motor = new Motor()
    direksiyon = new Direksiyon()
    solaGit() {
    direksiyon.solaKir()
    motor.hızıArtır() }}

    View full-size slide

  14. Araba
    Motor
    Direksiyon
    solaGit

    View full-size slide

  15. Reducer ile Kompozisyon
    • Nesne ve class'lar yerine fonksiyonlar

    • Her fonksiyon başka bir fonksiyonu çağırabilir

    • Dönen sonucu ilgili yere yazar

    View full-size slide

  16. Örnek
    defaultState = {
    motor: MotorReducer(undefined),
    direksiyon: DireksiyonReducer(undefined)
    };
    function ArabaReducer(state = defaultState, action) {
    yeniMotor = MotorReducer(state.motor, action);
    yeniDireksiyon = DireksiyonReducer(state.direksiyon, action);
    return { motor: yeniMotor, direksiyon: yeniDireksiyon };
    }

    View full-size slide

  17. Örnek
    defaultMotorState = {yon: undefined, hiz: undefined}
    function MotorReducer(state=defaultMotorState, action) {
    switch ...
    }
    defaultDireksiyonState = {yon: undefined}
    function DireksiyonReducer(state=defaultDireksiyonState, action) {
    switch ...
    }

    View full-size slide

  18. defaultState = {

    motor: MotorReducer(undefined),

    direksiyon: DireksiyonReducer(undefined)

    };

    function ArabaReducer(state = defaultState, action) {

    yeniMotor = MotorReducer(state.motor, action);

    yeniDireksiyon = DireksiyonReducer(state.direksiyon, action);

    return { motor: yeniMotor, direksiyon: yeniDireksiyon };

    }

    defaultMotorState = {yon: undefined, hiz: undefined}

    function MotorReducer(state=defaultMotorState, action) {...}

    defaultDireksiyonState = {yon: undefined}

    function DireksiyonReducer(state=defaultDireksiyonState, action) {...}

    View full-size slide

  19. • Anne reducer, kendisine gelen butun
    mesajlari cocuk reducerlara gonderir.
    • Cocuklar gelen mesaj sonrasi kendi
    yeni versiyonlarini anneye doner.
    • Anne, artik cocuklarin yeni
    versiyonlarini icinde kaydeder.

    View full-size slide

  20. • Aslinda anne reducer, kendisine gelen her eylemi
    dogrudan cocuklara gondermek zorunda degildir

    • Eylem turune gore sadece belli bir cocuga gonderebilir

    • Ama genelde Redux uygulamalarinda bir degisiklik oldugu
    zaman bu butun cocuklara haber verilir.

    • Bu sekilde her cocuk, son duruma gore kendisine
    cekiduzen verir.

    View full-size slide

  21. Araba
    Motor
    Direksiyon
    solaGit Görüntü

    View full-size slide

  22. Kaynak: http://www.sohamkamani.com/
    blog/
    2017/03/31/react-redux-connect-explained/

    View full-size slide

  23. Klasik Nesne Yönelimli
    Programlamayla Karşılaştırma
    • Alan Kay: Nesne yönelimli mesajlaşmanın temeli haberleşmedir!

    • Varsayılan olarak tek bir nesneye haber gönderilir.

    • Diğer nesnelerin bundan haberi olması gerekirse bu haber diğerlerine elle
    gönderilir

    • Sorun? Toplu haberleşme yok

    • Çözüm: Olay Otobüsü!

    • Bütün olaylar bir otobüse gönderilir. Otobüsteki herkese haber verilir

    • Redux aslında bir olay otobüsü (event bus) örneğidir

    • Sayfada olan her olay, merkezi bir noktaya gider

    View full-size slide

  24. Verinin Görüntüye
    Dönüşmesi
    • React: f(veri) = görüntü

    • Verinin değiştiğinden bir React görüntüsü nasıl haberdar
    olur?

    • setState ile!

    • O zaman Redux'ta bir değişim olunca biz de istediğimiz
    verileri alıp setState yapalım!

    • Bizim Redux'a abone olmamız gerek! subscribe!

    View full-size slide

  25. Abonelik
    storedanBanaGerekenler = function (db) {

    return {direksiyon: db.direksiyon} }

    class AboneBilesen {

    constructor() {

    this.state = storedanBanaGerekenler(store.getState())

    store.subscribe(() => {

    this.setState(storedanBanaGerekenler(store))

    View full-size slide

  26. Artık bileşenimin state'i
    ile store'daki state hep
    senkronize!

    View full-size slide

  27. Render kısmı?
    render() {

    return (

    Direksiyon bilgisi: {this.state.direksiyon.yon}
    yonunde

    }

    View full-size slide

  28. Render kismini ayri bir
    bilesen alalim
    • class DireksiyonAbonesi

    • Store ile senkron olur

    • Tum state'ini props olarak asagidaki goruntuye aktarir

    • class DireksiyonGoruntusu

    • Sadece goruntuyu gosterir

    View full-size slide

  29. Dükkan
    Direksiyon
    Abonesi
    Direksiyon
    Görüntüsü
    1. Gerçek veri bu dükkanın içinde
    2. Dükkandaki veri değiştiğinde
    aboneye gönderiliyor
    3. Abone, veriyi state'te saklayıp
    görüntüye prop olarak aktarıyor
    4. Görüntüde bir olay olursa
    bu dükkana haber veriliyor
    5. Dükkan gelen haber sonrası
    kendini güncelliyor
    6. Dükkandaki veri değiştiğinde
    aboneye gönderiliyor

    View full-size slide

  30. Abonelik Kısmı Ortaklaştırılabilir: Connect
    • Ortak olmayan tek kısım: storedanBanaGerekenler

    • Malzemeler:

    • Bir adet connect

    • Bir adet storedenBanaGerekenler fonksiyonu

    • Bir adet sadece props alan akılsız görüntü

    • Reçete

    • connect'e önce storedenBanaGerekenler'i sokun

    • 5 dakika hafif ateşte pişirin

    • Sonrasında akılsız görüntü ekleyip servis yapın
    connect(storedenBanaGerekenler)
    (akılsızGörüntü)

    View full-size slide

  31. Connect nereden geliyor?
    • Redux'tan değil

    • Redux, React'ten tamamen bağımsız

    • İsterseniz Angular'da kullanin, isterseniz port edip C#'ta

    • Bağlantıyı sağlayan kütüphane: react-redux

    View full-size slide

  32. connect nasıl çalışıyor?
    • connect gizli olarak store'a bağlanıyor

    • İki yöntem var: Ya store'a doğrudan erişimimiz olacak, ya da store
    bize bir şekilde gönderilecek

    • ikinci yöntemi kullanıyor

    • Context ile!

    • React sadece state ve props'tan oluşmuyor

    • Global veriler Context ile tüm alt seviye bileşenlere gönderilebilir!

    • React genel yapısına ters! Ama büyük kolaylık

    View full-size slide

  33. connect
    • Connect, önce yeni bir bileşen oluşturuyor.

    • Sonrasında, context içindeki store'a abone oluyor.

    • Abone haberi gelince setState yapıyor

    • render'da ise akılsız görüntüye bu verileri gönderiyor!

    • Peki context'e store'u kim koydu?

    View full-size slide

  34. Provider
    • Sağlayıcı

    • Görevi: Store'u aşağı sağlamak

    • Bu kadar

    • En tepede bir tane Provider içine koyuyoruz her şeyi

    • Store'u tüm çocuklara context üzerinden sunuyor

    • Connect de bundan yararlanıyor

    • Bu kadar basit

    View full-size slide

  35. Kaynak: http://www.sohamkamani.com/blog/
    2017/03/31/react-redux-connect-explained/

    View full-size slide

  36. Peki aksiyonlar?
    • Her çocuk, store'a dolaylı olarak erişimli

    • Dolayısıyla çocuk dispatch yapabilir

    • Bu haber merkeze (depoya) gider

    • Sonrasında olanlar olur!

    • connect yapınca her çocuğa dispatch fonksiyonu geçer

    • Çocuk içeride bu olayi merkeze haber verir:

    • dispatch({type: "BANA_BIR_SEYLER_OLDU"}

    View full-size slide

  37. connect seviyesinde
    pisirilmis eylem tarifi
    • Dispath yari pismis bir yemek

    • Cocuklara dogrudan dispatch'i vermek yerine yetkilerini kismen ellerinden
    almak icin pisirilmis halde verilebilir

    dispatchiPisir(dispatch) {
    return {tiklaFonksiyonu: () => {
    dispatch({type: "BANA_TIKLADIR"})
    }
    • Artik cocuga tiklaFonksiyonu diye pismis bir eylem gider

    • Cocuk sadece this.props.tiklaFonksiyonu() diyerek bu fonksiyonu cagirir

    View full-size slide

  38. connect son hali
    • Bir adet connect fonksiyonu

    • Bir adet db alan select yapan mapStateToProps fn.

    • Bir adet dispatch yapan pismis eylemler olusturan mapDispatchToProps

    • Bir adet saf, akilsiz bilesen

    • Once connect'e mapStateToProps ve mapDispatchToProps ekleyin

    • Kisik ateste 5 dakika pistikten sonra akilsiz bileseni ekleyin

    • connect(mapStateToProps, mapDispatchToProps)(akilsizBilesen)

    • Artik elinizde akilli bir bilesen var

    View full-size slide

  39. Kaynak: http://www.sohamkamani.com/blog/2017/03/31/react-redux-connect-
    explained/

    View full-size slide

  40. Akilli ve Akilsiz Bilesenler
    • Container vs Pure

    • Konteyner vs Saf

    • Smart vs Dumb

    • Akilli vs Akilsiz

    • Bir nevi mapStateToProps ve mapDispatchToProps,
    merkez ile ilcelerin baglantisini sagliyor

    • Baglanti = Connect

    View full-size slide

  41. Merkezi Yapinin Diger
    Avantajlari
    • Butun haberler merkeze gidiyor

    • Merkez her seyden haberdar

    • Her seye merkez haber veriyor

    • Her seyi fisleyebiliyor

    • Istedigi mesajlari iletmeyebiliyor

    • Isterse gecmisi yeniden yazabiliyor ya da eylemleri geri
    alabiliyor

    View full-size slide

  42. Merkezi Yapinin Diger
    Dezavantajlari
    • Merkeze cok yuk binebiliyor

    • Bir bilesenin kendi icinde halledebilecegi bir sey icin bile
    merkeze danismasi gerekiyor

    • Yerel verileri icin state kullanilabilir, menu dropdown state
    gibi

    • Ama diger tum veriler merkezde toplanmali

    View full-size slide

  43. Sonuç
    • Sunucu tarafında veriler veritabanında saklanıyor

    • Önyüzde de merkezi bir yönetime ve veritabanına gerek var

    • Nesne yönelimli programlamaya alternatif olarak veriyi tek bir
    nesnede toplayalım

    • Bu nesnedeki verileri tüm uygulamaya aktaralım

    • Görüntü katmanı yeni veri gelince React gibi farkları optimize
    eden bir yapıda tüm görüntüyü baştan oluştursun

    • Görüntüde olan olaylar merkeze gönderilsin

    View full-size slide