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. Veri (Model) Görüntü Kontrolcü MVC Model - View - Controller

    Model - Görüntü - Kontrolcü React, taslaklar...
  2. 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
  3. 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
  4. Model / Veri Ambarı / Depo / Repo / Dükkan

    / Store / Database! Store - getState() - dispatch(action) - subscribe(listener)
  5. 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; } }
  6. 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; } }
  7. Örnek • depo.getState() • aboneFonksiyonu = () => log("Depo degisti")

    • depo.subscribe(aboneFonksiyonu) • depo.dispatch({type: 'SET_TODO'}) • depo.getState()
  8. veriyiDegistir (state, action) => state • veriyiDegistir metodu • Iki

    veri girdi, bir tane cikti • Sayi azaldi: Ingilizce reduce • Bu nedene reducer denilmis redux'ta
  9. 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
  10. 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'})
  11. 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() }}
  12. Reducer ile Kompozisyon • Nesne ve class'lar yerine fonksiyonlar •

    Her fonksiyon başka bir fonksiyonu çağırabilir • Dönen sonucu ilgili yere yazar
  13. Ö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 }; }
  14. Örnek defaultMotorState = {yon: undefined, hiz: undefined} function MotorReducer(state=defaultMotorState, action)

    { switch ... } defaultDireksiyonState = {yon: undefined} function DireksiyonReducer(state=defaultDireksiyonState, action) { switch ... }
  15. 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) {...}
  16. • 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.
  17. • 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.
  18. 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
  19. 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!
  20. Abonelik storedanBanaGerekenler = function (db) { return {direksiyon: db.direksiyon} }

    class AboneBilesen { constructor() { this.state = storedanBanaGerekenler(store.getState()) store.subscribe(() => { this.setState(storedanBanaGerekenler(store))
  21. 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
  22. 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
  23. 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ü)
  24. 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
  25. 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
  26. 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?
  27. 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
  28. 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"}
  29. 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
  30. 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
  31. 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
  32. 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
  33. 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
  34. 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