REACT DOC SERIES
React Docs -2 (DOM Tree Problems)
React Doc Gelişmiş Kılavuz içerisinde yer alan konuların bazılarına Portals, Refs, React Context bu yazıda değineceğim.
Bir önceki yazımda React Docs -1 (Temel Konseptler) ile JSX, Rendering Elements, Components And Props, State LifeCycle, Handling Events, Conditional Rendering, List And Keys, Forms, Lifting State Up, Composition vs Inheritance konularını anlatmıştım.
Bu yazıda https://reactjs.org/docs/getting-started.html sayfasından Gelişmiş Kılavuz üzerindeki dokümantasyonu yorumlamaya devam ediyorum.
1. React Portals
Bir ekranın Rendering Ağaç Hiyerarşisi dışında ekrandaki bileşen ile ilgili bilgiler göstermek istediğiniz Modal, Popup vb.. yapılarda kullanılır.
Ne Tarzda Teknik İhtiyaç Bulunur ?
- Modal ilgili bileşenden tamamen farklı bir pozisyonda pencerede düğmeye bastığınız düğmenin içeriğini dialog içerisinde render etmek
- Modal ana yapıdan farklı render ederek bu ekranı en önde, bu ekranın arkasında kalan kısmı daha kararmış göstermek istersek
Görüldüğü gibi Rendering Ağacında farklı bir dalda olması lazım ki hem z-index hemde pozisyon olarak event tetiklendiği düğüm’den etkilenmesin.
Yukarıda görüleceği gibi Panelin içerisinde bulunan XY içeriğini sanal olarak Root ağacı değilde Portal yani root dışındaki başka bir div içerisine renderlenmesi sağlar. Bunun için API’deki aşağıdaki komutu kullanmanız yeterli olur.
ReactDOM.createPortal(child, container)
Bu sayede root dışında başka bir div içerisinde render edilmiş bileşenimizde
overflow: hidden
z-index
kavramlarını ana yapıyı etkilemeden rahatlıkla kullanabiliriz.
Aşağıda ReactDOM.createElement yerine ReactDOM.createPortal ile nasıl farklı Portal oluşturabildiğinizi görebilirsiniz.
Burda bir önemli konuda UI Event Mekanizmasındaki sağladığı avantajdır. Bu yazıyı bu linkten isteyen detaylı okuyabilir.
UI Event Mekanizması
*.onClick tüm HTMLElement genel bir listener eklediğimizde nasıl bir davranışta bulunacak. Çünkü HTML elemanları iç içe bulunan yapılardır ve Event tetikleme hangi sırada gerçekleşecektir? Burada 2 tip model bulunur.
-----------------------------------
| HTML> BODY> FORM > DIV |
| ------------------------- |
| |P | |
| ------------------------- |
| |
-----------------------------------
- Event Capturing: Bu yöntemde tıklanan elemana yukarıdan aşağıya doğru ulaşılır. HTML → BODY → FORM → DIV → P olarak eventleri oluşturur.
- Event Bubbling: Bu yöntemde de tıklanan elemanda aşağıdan yukarıya doğru eventler oluşturulur. P → DIV → FORM → BODY → HTML
Bu eventlerin bir sonraki seviyeye atlamamasını engellemek için event.stopPropagation() metodu kullanılır. Bu sayede sadece ilgili seviyeye kadar event ilerlemesi sağlanıp sonraki kısımlarda event işleyişi durdurulabilir. Aynı işlem önceden event.cancelBubble = true; ilede yapılabilmektedir.
Portal Event Bubbling Mekanizması
Portal DOM hiyerarşisinde başka bir ağaç altında olsa bile React VDOM bulunduğu alt eleman olarak algılanır. Context alt elemanın bir portal olup olmadığı ilgilenmeksizin aynı React elemanı gibi davranacaktır. Bu sayede görsel bir takım imkanlardan faydalanırken, Modal/Popup üzerinde gerçekleşen eventleride tetiklemenin gerçekleştiği bileşenden yakalayıp, o Context içerisinde işlem ilerletilir ve Modal kapatılması gerçekleştirilebilir.
2. React Refs
İsminden de anlaşılacağı gibi Render edilen objenin referansı. Normalda React çalışma mantığına biraz ters bir yaklaşım. Çünkü React, jQuery gibi bileşenlerin DOM üzerindeki Id veya class erişip bunlar üzerinden düzenleyerek değişiklik yapmaz. Bunun yerine merkezine Bileşenleri koyup state ve prop değişimi ile bileşenlerin tekrar render edilerek güncellenmesi üzerine bir yöntem izler.
Ama bu bazı durumlar için yeterli olmaz. Örneğin
- DOM ağacında render edilen bir nesnenin pozisyon bilgilerine event gerçekleştiğinde ihtiyaç duyulması.
- Ekranda bir düğmeye bastığımızda ilgili bileşenin focus metodunun çağrılması.
- SVG veya Canvas üzerine çizim yapan 3rd Party bir kütüphane ekrana çizim yaptıktan sonra Layout değişimine göre tekrar sığdırılması.
- Farklı bileşenlerde DOM üzerinde daha derinlerde WebAPI bağlayarak işler yapmak istendiğinde (MutationObserver)
- vb..
Aşağıdaki örnekte görüleceği gibi SemanticUI React bileşenlerinden Popup tetikleyen bileşen ile popup üzerinde çıkacağı bileşen birbirinden farklı pozisyonlarda olsun dediğimizde. Bu durum DOM olarak başka düğüm hiyerarşisinde olmasını gerektirecektir. Trigger Popup içerisinde olan Hello bilgisi nasıl olacak ta başka bir bileşenin pozisyonunu kullanarak oluşturulabilir ?
“Here” bileşenin referans bilgisini React.useRef ile bir değişkene atayıp, bunu istediğimiz bileşenlere referans olarak geçirebiliriz.
Ref API
Peki RefAPI arka planda nasıl çalışıyor. Ağaçta başka bir düğüm altında yer alan nesnenin referansını
this.myRef = React.createRef() //Referansı Alma
const node = this.myRef.current // Referansın HTML elemanına erişim sağlanabilir
Ref Focus
Bir Input elemanına başka bir düğmeye basınca focus olabilmesi için o Input HTML nesnesine erişmek gerekiyor. Aşağıdaki örneğin aşağıdaki input nesnesinin referansını aldıktan sonra aşağıdaki kodla ilgili eleman focus verilebilir.
this.textInput.current.focus()
3. React Context
Aslında bu konuya girmeden önce UI kısmındaki paylaşım konusunu ben 2 şekilde düşünüyorum.
- State Paylaşımı (Lifting State Up, Redux, Context, Hooks)
- Logic / Behaviour Paylaşımı (Inheritance, Composition, High Order Components, React Render Props, Hooks)
Context bizim State paylaşımı yapmamızı sağlayan bir mekanizmadır. Lifting State Up Developer kendisinin bir yapı oluşturması, Redux dışarıdan bir kütüphane kullanılması yerine React API içerisinde state paylaşımını sağlayacak bir yapıdır.
Wrapping yapısından dolayı iç içe kodun okunmasını zorlaştıran bir yapısı olduğu için ben projelerde kullanmıyorum genelde Ama Redux kullanılmayan Theme, Language vb.. tüm Node ilgilendiren yerlerde kullanılabilir.
Tipik bir React uygulamasında veri props aracılığıyla yukarıdan aşağıya aktarılır (üst bileşenlerden alt bileşenlere), fakat bu bir uygulamada birçok bileşene ihtiyaç duyulan belirli tipteki props (örneğin; i18n, arayüz teması) için kullanışsız olabilir.
Context, bileşen ağacın her bir seviyesi üzerinden prop geçirmeden, bileşenler arasında bu değerleri paylaşmanın bir yolunu sağlar.
React Context Generation
React Context kullanımındaki bileşenler;
- State tutan Context (ThemeContext)
- Context sağlayan Provider (ThemeContextProvider)
- Bu Context tüketecek Consumer (ThemeContextConsumer)
oluşur. Aşağıdaki örnekte ThemeContextProvider nasıl oluşturulduğunu görebilirsiniz.
Consumers
Bu Context kullanan 2 tane bileşenimiz olsun. Birisi Image diğeride Button. Bu 2 bileşen render edilirken ThemeContext.Consumer wrap edildiğini ve bu sayede ThemeContext kullanabiliyorlar.
Wrapping
Burada bu Context Consumer bu yapılardan faydalanabilmesi için Provider ilgili bileşenleri sarmalaması lazımdır. Bu sayede içerideki bileşen Consumers bu Context verisini kullanabilir.
Referanslar
Okumaya Devam Et 😃
Bu yazının devamı veya yazı grubundaki diğer yazılara erişmek için bu linke tıklayabilirsiniz.