DOM API USAGE SERIES
React ile DOM Kullanımı
React DOM API’sini nasıl kullanıyor. Virtual DOM ile kullanıcının DOM ile çok uğraşmasını gerektirmeden bileşenler üzerine odaklanmasını nasıl sağlıyor. JSX arkaplanda nasıl React API call dönüştürülüyor.
Bu yazıyı daha önceden yazmış olduğum DOM API Kullanım Yöntemleri yazısının bir devamı olarak yazıyorum. Bir çok kavramı tek bir yazıda ele almanın yaratacağı karmaşıklıktan kaçmak için bu şekilde bir yönteme başvurdum.
React DOM API kullanımı nasıl anlatayım derken karşıma aşağıdaki Kent C. Dodds “Super Simple Start to React” yazısı karşıma çıktı. Yazının kendisini okumanızı ve yazının içerisindeki videoları izlemenizi öneririm. Benim baştan bir yazı üretmeme gerek yok. Bu yazıda bu blog yazısından ve neden hoşuma gittiğinden bahsedeceğim.
React kullanıcıları hemen React projesi oluştururken Create React App projesinden bir proje template oluşturup aşağıdaki kodu çalıştırarak basit bir template üzerinden projelerini geliştirmeye başlarlar.
npx create-react-app my-app
Peki bu proje template arka planı nasıl. React arka planda DOM API si ile nasıl iletişim kuruyor. “Super Simple Start to React” yazısı bunun bir kısmını anlatıyor. Birde işin Virtual DOM kısmı bulunuyor.
1. Blog Yazısının Analizi
Blog Yazı 4 kısımdan oluşuyor.
1.1 Kısım JS ile Kendi Root Id Nasıl Element Oluşturursun.
Body içerisinde tanımlayacağımız bir root elemanın içerisine JS script ile document.createElement ile istediğimiz elemanları oluşturup seçtiğimiz bir elemanın içerisine bunu append ile ekleyebiliriz. Bu default JS davranışı
1.2 document.createElement yerine React.createElement
DOM API Document Objesi JS içerisinde gömülü hazır bir şekilde gelmektedir ve document.createElement arka planda bir DOM Node oluşturur . Bunu wrap eden bir mekanizma oluşturmak için react.development kütüphanesini yüklüyoruz.
Burda react.createElement nasıl React Node oluşturduğunu görebilirsiniz. Burdaki fark kodu Wrap etmemizin sebebi ileride anlatacağımız DOM yapısına direk olarak Node append edilmemesi. Öncelikle Virtual DOM bu node yansıltılması sonrasında alınacak Diff sonucunda gerçek DOM üzerine bu değişikliklerin yansıtılacak olmasıdır.
Arkaplanda nasıl bir React Node oluşturulur.
Not : Aslında bahsettiğimiz tüm framework (JQuery, Vue, Backbone, Ember vb…) kendi DOM element yapısını wrap eder. Burda Wrap ettikleri bu DOM yapısını gerçek DOM nasıl yansıttıkları önemli Eski kütüphaneler bunu DOM’a direk yansıtmakta bulurken, Vue ve React gibi kütüphaneler Virtual DOM kullanmayı savunmuşlar, Svelte bunu gereksiz görmektedir. Polymer gibi kütüphanelerde Shadow DOM kullanmaktadır.
- DOM (Real DOM)
- Virtual DOM
- Shadow DOM
1.3 HTML node.append yerine ReactDOM.render() kullanılması.
React direk DOM append etmek yerine kendi ReactDOM API render fonksiyonunu kullanarak Virtual DOM üzerine render işlemi gerçekleştirir.
1.4. createElement yerine JSX kullanımı
React.createElement içerisinde API div elemanları tanımlamız kolay değildir kolay olan declerative (Declarative Kavramı) bir tanım olan HTML tanımlamalarıdır. Peki bunu JS içerisinden nasıl yapabiliriz. Bunun cevabı JSX’dir. JSX Javascript içerisinde HTML elemanları hatta kendi oluşturduğunuz bileşen taglarını/yapılarını HTML elementleri gibi kullanabilmenizi sağlayan altyapıdır.
Bunun browser çalıştırabilmesi mümkün değildir. Çünkü browser standardı olmayan bir yapıdır. Bu aşamada Babel devreye girer. Yazdığımı bu JS dosyasını arkaplanda createElement API’sine dönüştürebilecek bir transpiler/compiler
Babel normalde prod ortamında çalıştırılmayacak bir kütüphanedir. Bizim react projesi oluşturup webpack projeyi build ettğimizde hem Babel JSX üzerinden geçecek gerekli API’ler oluşacak hemde Webpack JS, CSS, Asset bundle edip tek dosyalarda birleştirip production ortamına hazırlayacaktır.
aşağıda gördüğümüz aslında basit bir JSX kullanımıdır. Bu arkaplanda yukarıdaki örnekteki createElement yapısına dönüştürülür.
<div>Hello World</div>
2. ReactDOM.render Nasıl Çalışıyor ? Virtual DOM
Yukarıda aslında blog yazısı analizim bitti. Ama ben biraz daha derinlere inerek ReactDOM.render() içerisinde neler yapıldığını anlatmak istiyorum. Burada React direk DOM yapısına erişmez render işlemini Virtual DOM üzerine yapar. Peki neden Virtual DOM. Neden DOM API’sini kullanmıyoruz.
JQuery yazarı The DOM is a Mess. konuşmasında DOM API JS direk kullanmanın zorluklarını, karmaşıklığını JQuery ile bunun üzerine nasıl bir katman oluşturmak istediğini anlatmaktadır.
JQuery ile çok ince bir soyutlama katmanıdır. DOM id, class üzerinden erişmeler binding işlemleri devam etmektedir. İlk büyük değişiklikler Backbone.js ile gelmiştir. Ama backbone bir MVC yapısıdır. Sadece View kütüphanesi DOM logiclerini nasıl kodun içerisinden çıkarabiliriz. Bunun yöntemini React VirtualDOM kullanmakta bulmuştur. VirtualDOM hem kullanıcından bu binding sürecini uzaklaştırmış hemde güncelleme işlemlerinin performans işini Diffing Algoritmalarına bırakarak geliştiricilerin performans ile uğraşma probleminide çözmüştür.
A. Normal Bir HTML Rendering Akışı
- HTML parse edilerek DOM ağacı oluşturulur,
2. JS ile DOM API gelen değişiklikler DOM Ağacını günceller
3. StyleSheet CSS tarafından parse edilir. StyleSheet kuralları oluşturulur
4. DOM Tree ve Style Rules birleştirilerek Render Tree oluşturulur.
5. Layout yani tarayıcının özellikleri (Dekstop, Mobile, Çözünürlük vb..) göre ekrana boyama işlemi gerçekleştirilir.
B. Virtual DOM Akışı
(Vue, React) SPA (Single Page Application) tek bir sayfa içerisinde bir çok div hiyerarşisinin yönetilmesini içerir. DOM yönetmek, (node ekleme, çıkarma, güncelleme) ve buradaki eventleri yönetmek normal soyutlama katmanları ile oldukça zordur. Bunun için VirtualDOM size DOM üzerine bir sanal soyutlama kavramı sunar ve geliştiriciler artık bileşen geliştirmeye odaklanabilirler aynı legolar gibi , kocaman büyük projeyi tek bir html içerisinde oluşturmak yerine lego parçalarını yapıp birleştirmeye odaklanabilirler artık.
3. React Component Lifecycle
React Bileşen yapısının (Hook hariç) state yapısı aşağıdaki gibidir.
3.1 Mounting
3.2 Updating
static getDerivedStateFromProps()
shouldComponentUpdate()
render()
getSnapshotBeforeUpdate()
componentDidUpdate()
3.3 Unmounting
3.4 Error Handling
Bu bileşen yapısının yaşam döngüsü arkaplanda nasıl işletildiği , event trigger yapılarının nasıl ele alındığı aşağıdaki grafikte anlatılmaktadır.
4. Diffing Algorithm
Virtual DOM nasıl çalışır peki. DOM hiyerarşisini bir benzerini React bellekte tutar. Sizin ReactDOM.render(app) yaptığınızda aslında bellekte olan değişikliklerin diff(farkını) alarak bunu gerçek DOM yansıtır. Bunun için . Reconciliation denen bir mekanizma kullanır.
Referanslar
- Kent C. Dodds Super Simple Start to React blog yazısı
- https://tr.reactjs.org/
- https://reactjs.org/docs/faq-internals.html
- https://reactjs.org/docs/reconciliation.html
- https://reactkungfu.com/2015/10/the-difference-between-virtual-dom-and-dom/
- https://medium.com/@deathmood/how-to-write-your-own-virtual-dom-ee74acc13060
Okumaya Devam Et 😃
Bu yazının devamı veya yazı grubundaki diğer yazılara erişmek için bu linke tıklayabilirsiniz.