React Routing
React Router — 1 (Temel Kavramlar)
Web Uygulamaları genelde, birden fazla sayfadan oluşur, sayfalar bazen iç içe sekmeler, ve alt bölümlerden oluşur. İşte tüm bu sayfalar ve sayfalar içerisindeki sekme ve bölümler içerisinde gezme işlemine routing diyoruz.
Routing kavramı Web Sayfaları ve Web Uygulamalarını geliştirmeye başladığımız ilk ilk günden beri var olan bir konu. Sayfalar ve o sayfalara yönlendiren linkler Internetin ilk var olduğu, HTML sayfalar tasarladığımız günden beri hayatımızda web sayfaları ve linkler olarak yer alıyorlar.
Bundan dolayı da Web Uygulaması geliştirmek için kullandığımız tüm kütüphane ve framework’ ler bu konuyu geliştiricilerden soyutlayarak daha basit şekilde uygulama geliştirmelerini sağlamışlardır. Hangi kütüphane ve ekosistemine bakarsanız Örneğin Backbone, Ember, Angular, Vue, React, Svelte … hepsinde de bir veya birden fazla routing kütüphanesi olduğunu görebilirsiniz.
Web uygulamasında ilgili sayfayı açtığınızda ana sayfaya ulaşırsınız buradaki linkler ile domain adresi üzerinden alt kırılım ve parametreler ile uygulamanın diğer alt sayfalarına ve bu sayfalar ile ilgili içeriklere ulaşırsınız.
Örneğin aşağıda onurdayibasi.com ile onurdayibasi.com/search arasında farklı sayfaların ve içeriklerin gösterilmesi için yapılan işlemlere routing diyoruz.
Özetle routing web uygulamalarında en önemli konseptlerinden birisidir ve framework’ ler geliştiricileri Web API seviyesinde routing ile uğraştırmaktan soyutlayacak kütüphaneler sunarlar, Örneğin
- Backbone Routing
- Ember Routing
- Angular Routing
- React → (React Router, React Location, Next.JS Router)
- Vue → (Vue Router)
- Svelte → (Svelte Navigator)
Temelde bu kütüphaneler WebAPI üzerindeki URL API, History API, Location API, SearchParams API kullanarak geliştiricilere daha üst seviyede bir soyutlama ile yazılım geliştirme imkanı sunarlar.
Sayfaları ve sayfalar içerisindeki sekmeleri adreslememiz lazım ki, bu sayfalara linkler üzerinden erişebilelim, işte burada da karşımıza URL çıkıyor, URL aslında bir adresleme yöntemi sunar.
URL yakından baktığımızda bizim uygulamamızı ayıran temel parçaların hostname/port → sonra gelen pathname, search ve hash birleşiminin oluşturduğu path kısmından oluştuğunu görebilirsiniz.
Burada Router Client Side’ mı yoksa Server Side üzerinden mi yönlendirme yapısı kuracaksanız. Bu seçiminize göre size ilk baştan bazı alternatifler sunar. Web API si üzerinde kurguladığınız bazı yapılar Backend çağırımı yapmaz iken bazıları Backend tüm sayfa isteğinde bulunur.
Routing İle ilgili Web API’ler
Routing için hangi kütüphaneyi kullanırsak kullanalım temelde Web API üzerindeki bazı fonksiyonlardan faydalanıyordur. Bu bölümde bu fonksiyonlar üzerinde duracağım.
1. History API
History API, kullanıcının gezmiş olduğu URL tutarak bunun üzerinde ileriye ve geriye gitmeyi sağlar. Length(uzunluk) bilgisi size kaç defa geri gidebileceğiniz ile ilgili bilgi verir. Örneğin bu değer 0 ise geri gitme düğmesini uygulamada kendiniz koymuşsanız bunu gizleyebilir veya disabled hale getirebilirsiniz.
//window.history
length => kaç tane URL gezmişsin history tutar.back() => bir germiş sayfaya gider
forward() => bir sonraki sayfaye gider (geri gelmişseniz)
go() => // window.history.go(-4);
React gibi SPA (Single Page App) açısından önemli olan bir fonksiyon bulunur pushState. Bu fonksiyon URL değişikliklerinde Backend isteği ile sayfa yüklenmeden direk tarayıcıdaki session içerisinde bu işlemi yapmamızı sağlar.
Buda bize SPA yani desktop/mobile bir native uygulama hissiyatı verir. Yani uygulama içerisinde sayfalar sürekli değişmez sayfanın içerisindeki içerik değişmiş olur.
history.pushState({page: 1}, "title 1", "?page=1")
history.pushState({page: 2}, "title 2", "?page=2")
history.replaceState({page: 3}, "title 3", "?page=3")
Aslında bu tarayıcı adres kısmındaki URL değiştirirken, bu işlemi backend bir istek atmadan gerçekleştirir. Eski zamanlarda bu işler için location hash kullanılırdı. Örneğin twitter.com/#home twitter.com/#follower gittiğinizde sadece hash değişikliği olur bu backend tetiklemezde ClientSide JS ile bu değişikliği dinler ve buna göre ajax ile request atardık. Şimdi pushState ile durum aynı şekilde çalışır.
window.location = “#foo”
Client (İstemci)’ de peki bu değişimleri nasıl ele alacağız. 2 alternatif yöntem var.
- Ya belli aralıklarsa sayfanızın URL sorgulayıp bunu parse edip one göre karar verecek yapılar kuracağız. onpopstate mevcut URL değişikliklerini anlayıp buna göre davranacaksınız.
window.onpopstate = function(event) {
alert(`location: ${document.location},
state: ${JSON.stringify(event.state)}`)
}
- Veya routing üzerinden bu yönetimi gerçekleştirip Route Context içerisinde bu bilgileri tutup bilelenlere bu bilgilere Context üzerinden dağıtım yapacağız.
Not: React Router vb.. kütüphanelerde Provider Pattern ile aslında arkaplanda Context tutmaktadır.
2. Location API
Location API window.location kodu ile adres çubuğunda yazan URL erişip bunu işlememize olanak sağlar.
Aynı zamanda URL değiştirerek farklı sayfalara yönetmesi için,
//window.location
href,hostname,protocol,hash, origin, search, pathname => erişmenizi sağlarassign(), replace(), reload() => sayfayı yeniden yüklemeyi veya farklı sayfalara yönelmeyi sağlar.
3. URL API
URL API , href veya bir adresi string olarak aldığınızda bunu parse etmenizi veya kendi URL oluşturmanızı sağlar. Aşağıda örnek bir URL objesini görebilirsiniz.
Veya kendiniz sıfırdan bir URL objesi oluşturup bunun değişkenleri olan
- hash
- host,
- hostname,
- href
- origin
- password
- pathname
- port
- protocol
- search
- searchParams
- username
alanlarına erişip değerlerini güncelleyebilirsiniz.
toString ve toJSON ile URL Objesini normalize ederek string ve json dönüştürebilirsiniz.
4. URL Search Params
Search Params API’de aynı URL apisine oldukça benzer fakat Search parametrelerine odaklanmıştır bir API’dir. Search parametreleri üzerine gelen parametre string alıp size search parametre değerlerini döner.
Veya parametreleri kullanarak search url oluşturabiliriz
React Router
Web API yani tarayıcıda bulunan API sizin yazdığınız JS uygulamasının işletim sistemi seviyesi API’lere erişime limitli şekilde ulaşmasına olanak sağlar.
Ama bu seviye çok low level bir seviyedir. Web Uygulamaları için istenilen bir soyutlama ile Routing fonksiyonlarını sağlayamaz, bunun için sizin birçok util fonksiyon yazmanız gerekir. Çünkü Web Uygulamaları belli bileşenler/sayfalar ile eşlenmesi ve bunların ekrandaki render tetiklenmesi gerekir.
1. Router
- BrowserRouter: History API kullanarak sayfa yönlendirmelerini ve ilgili bileşenler ile bağlantılarını yapmamızı sağlar . React CSR yöntemlerinde genelde bu yöntem tercih edilir. History API(
pushState
,replaceState
and thepopstate
event) kullanarak URL ve UI sync tutar.
- HashRouter: CSR(Client Side Rendering) yöntemlerinde kullanılan window.location = “#foo” şeklinde server tetiklemeyen yönlendirmelerde kullanılır. pushState özelliğinden sonra kullanılması gerekmediği için # sunucu gereksinimi olmayan sadece sayfa içerisinde bir bölgeye odaklamak ve scroll etme işlemlerinde kullanılabilir. Bu kısımlar yerine komple HashRouter ihtiyacı genelde olmaz.
Bunun haricinde
- React Native Uygulamalarında kullanabileceğiniz NativeRouter,
- Server Side Rendering işlemlerinde kullanabileceğiniz StaticRouter
- Test Senaryolarında kullanabileceğiniz MemoryRouter
- ve kendi history objenizi verebileceğiniz unstable_HistoryRouter bulunur
2. Routes ve Route
Route bir path (adres tanımı) ve bu path bağlanacak olan bileşeni ifade eder.
Örneğin aşağıdaki örnekte Routes → içerisinde render edilebilen Route bileşenlerini görebilirsiniz. Route temelde bir path ve buna bağlı render edilecek element bileşeni vermeniz gerekir. Bunun arka planda react-router algoritmaları tarafından match (eşleştirilmeye) çalışıp eşleşen bileşene göre render edilmesini sağlar.
3. Link
Bizim ilgili web adreslerine gitmemiz ilgili sayfalar ve bileşenlere ulaşabilmemizi sağlayan HTML elemanlarıdır. <a href…>
Bu adres değişimleri için linkler ile birlikte API üzerinden window.location.href ile assign(), replace(), reload() kullanırız.
Ama SPA (Single Page App) için bize
- history.push gibi sunucuya gitmeden URL değişikliği sağlayıp bileşenle binding sağlatacak bir yapı lazım.
- Hem bu linkin üzerine sağ tıkladığınızda linkte opsiyonlar sunması veya Cmd/Ctrl+Click ilgili sayfayı yeni bir tab da açabilmelidir.
Link bileşeni to ile ilgili path yönlendirme işlemini gerçekleştirir.
NavLink: Link’in aktiflik durumunun önemli olduğu BreadCrumb ve NavigationMenu veya SideMenu gibi yapılarda kullanılmaya yönelik geliştirilmiştir. NavLink içerisinden isActive → tetiklenmesi durumunda farklı styling atamaları gerçekleştirebiliriz.
4. Navigation
Yukarıda Link <a href> li yapılardan bahsettik. Gelelim şimdi programla başka sayfalara yönlendirme ve redirect etme işine. Bu işlemi
- location.replace(href)
- location.assign(href)
.assign() browser history yeni bir href eklerken back tuşuna bastığınızda bir önceki ekrana dönebilirsiz. replace() ise history mevcut url değiştirerek mevcut url üzerine yazılması ve back tuşuna basınca mevcut URL dönüş yapılaMAmasını sağlamış olursunuz.
İşte React içerisinde declarative şekilde yapmanızı sağlayan ve bunun renderlenmesi ile sayfayı başka bir URL yönlendirme işlemini gerçekleştiren Navigate bileşenini kullanabilirsiniz.
<Navigate to="/dashboard" replace={true} />
5. Outlet
Nested Route’larda Routes içerisinde / altında Home, About, Contact farklı bileşenler render edilecek olsun, işte alt bileşenlere eşleşen pathler geldiğinde ilgili alt bileşenin render edilmesini sağlayan yapıya Outlet denir.
Örneğin Parent bir Layout’un içerisinde Home, About ve Contact olsun.
Bu bileşenlerin ilgili Layout içerisinde render edilebilmesi için gereklidir. Yani Outlet About, Contact, Home bileşenlerine pointer gibi düşünebilirsiniz.
Referanslar
- React da Sayfalar Arası Navigasyon
- Load Lazy When Routing
- URL Nedir ?
- URL API Nedir ?
- Browser API Nedir?
- Her Ortamda Çalışan Web Uygulamaları Geliştirme (URL Kullanımı)
Okumaya Devam Et 😃
Bu yazının devamı veya yazı grubundaki diğer yazılara (React Router) erişmek için bu linke tıklayabilirsiniz.