React — React Portal Nedir?
Bu yazının demo projesi GitHub’da bulunmaktadır — Demo projesinin bulunduğu GitHub Reposu → Repo
Merhaba arkadaşlar. Bugün sizlere React Portal nedir kullanım alanları nelerdir bunlardan bahsetmek istiyorum. Hadi başlayalım!
React Portal Nedir?
React Portal, bir parent component’e ait bir child componentini, bulunduğu DOM hiyerarşisinin dışında render etmenizi sağlar. Peki bu ne demek? Bir örnek üzerinden gösterelim.
Diyelim ki ürünün detayını içeren container içerisinde modal componenti child component olarak yer alıyor.
Bu durumda bu modal açıldığı zaman, bulunduğu container içerisinde (Yukarıdaki örnekte product-container içerisinde) açılmasını bekleriz çünkü ona bağlı şekilde yer almaktadır. Ama yukarıdaki örneğimizde görebileceğiniz üzere, Sepete Ekle butonuna tıkladığımız zaman açılan modal, ürün detayının olduğu container’da değil, ait olduğu parent’tan farklı bir yerde bulunan Sepetim kısmında render edildiğini görmekteyiz.
Daha detaylı bir inceleme yapacak olursak eğer; Sepete Ekle butonu product-container sınıfına ait bir parent eleman içerisinde render edilirken, açılan modal tamamiyle bu product-container’ın dışarısında bulunan bir yerde render edilmiştir.
Bunu yapmanın iki yolu olduğunu düşünebiliriz:
- Bir yolu, seçilen bilgiyi parent component’e gönderip daha sonrasında açılan bu modal’a props olarak tekrar göndermek olabilir.
Bu gibi bir yaklaşım küçük uygulamalarda basit olabilir ama Trendyol, Hepsiburada ve daha birçok kompleks uygulamalarda bu yaklaşım çok hızlı bir şekilde komplike hala gelebilir.
- Diğer yolu ise Modal’ı productDetail içerisinde kullansak bile React Portal ile bağlı olduğu parent’tan bağımsız olarak başka bir yere portal açarak render edilmesini sağlayabiliriz.
Portal ile bir child componentini DOM ağacının nasıl başka yerinde render edebileceğimize geçmeden önce React Portal’ın Syntax’ına bir bakalım!
Syntax
Bir portal React.createPortal ile oluşturulabilir:
ReactDom.createPortal(child,container)
- Burada child render edilmesini istediğimiz component’tir.
- container ise, bu child componentin render edilmesini istediğiniz DOM elemanıdır.
Demo
Demonun CodeSandbox haline aşağıdan erişebilirsiniz:
Şimdi yukarıda linkini paylaştığım demo’da neler olup bittiğine bakalım.
En başta belirttiğim Trendyol örneğinde olduğu gibi butona tıklandığı zaman açılan modal, Sepetim altında render edilmektedir. Bir navbar ekleyerek başlayalım.
Portal ile oluşturacağımız modal’ı, sepetim elemanın altında render edebilmek için üçüncü navigation item olan Sepetim elemanına bir id ekledik. Bunu birazdan nasıl kullanacağımıza değiniyor olacağız.
Birde en başta gösterdiğim gibi bir ürün detay componenti yapalım. Bu component içerisinde bir tane portal ile oluşturulmuş olan modal, diğerinde ise portal olmadan oluşturulan bir component bulunsun. Her iki modal’ıda tetikleyecek butonları da ekleyelim.
Portal ile oluşturulan Modal’a bakalım.
Gördüğünüz gibi, bu componentimiz 3 props almaktadır:
- Component’i render edip etmeyeceğimizi belirleyecek olan isOpenPortal boolean state’i.
- isOpenPortal state’inin değerini değiştirmemizi sağlayacak olan setIsOpenPortal hook metodu ve
- Sepete eklediğimiz ürünün ismini modal’a göndermek için productName props’u
createPortal syntax’ında belirttiğimiz gibi;
1- İlk parametre render edilecek olan child componentini içerir.
2- İkinci parametre ise bu child componentinin nerede render edilmek istendiğini içermektedir.
Biz sepetim elemanının altında bu modal’ı her zaman tetiklemek istediğimiz için id’si basket-item olan elemanı bulmasını ve orada bu modal’ın tetiklenmesini sağlarız.
Portal olmadan oluşturduğumuz modal’a bakacak olursak klasik bildiğimiz functional bir componenttir.
Her iki modal’a da aynı CSS özellikleri uygulanmaktadır. Ancak buradaki fark, portal’sız oluşturulan modal’ı tetiklediğimizde, bu modal product-detail içerisinde açılırken, portal ile oluşturulan modal, belirttiğimiz dom node’una bağlı olarak açılacaktır.
Sonuç
React portal, bir child component’ini DOM hiyerarşisinden ayrı olarak, React component ağacı üzerinden event propagation’ının default davranışlarını bozmadan render etmek istediğiniz zaman avantaj sağlamaktadır. Modal, tooltip, popup mesajları ve daha fazlasını render ederken fayda sağlar.
Portal Kullanırken Bilinmesi Gerekenler
- Event Bubbling olduğu gibi çalışır. — Portal node’un DOM’daki konumunun ne olduğunun önemi olmaksızın, event bubbling normal çalıştığı gibi çalışır.
- HTML mount noktası önceden tanımlanmalı — Portal’ın mount edileceği HTML DOM elemanı önceden tanımlanmış olmalı.
Bu yazının demo projesi GitHub’da bulunmaktadır — Demo projesinin bulunduğu GitHub Reposu → Repo
Umarım faydalı bir yazı olmuştur. Eksik veya yanlış olduğunu düşündüğünüz kısımları bana iletirseniz çok sevinirim :)
İletişim kanalları: Twitter — LinkedIn — Mail
Bir sonraki yazıda görüşmek üzere!
Referanslar
Bu yazının referansları:
https://medium.com/swlh/everything-you-need-to-know-about-react-portals-65f7c4f5f94a
https://www.hackages.io/blogs/react-portals-how-does-it-work