Bugün bazı gelişmiş React Router tekniklerini sizinle paylaşacağım için gerçekten heyecanlıyım. React Router, React uygulamalarımızda dinamik ve sorunsuz gezinme oluşturmamızı sağlayan muhteşem bir araçtır.
Yaygın olarak temel yönlendirme ihtiyaçları için kullanılsa da, yönlendirme yeteneklerinizi tamamen yeni bir seviyeye yükseltebilecek daha az bilinen bazı teknikler vardır.
Bugün zamanla keşfettiğim favorilerimden birkaçını paylaşacağım.
useNavigate
kullanılması ve Konum kancalarının useLocation
.
Bu makaleyi okumayı bitirdiğinizde, bu gelişmiş React Router tekniklerini güçlü bir şekilde kavrayacak ve bunları kendi projelerinizde uygulama konusunda kendinizi güvende hissedeceksiniz.
O halde hemen konuya dalalım ve yönlendirme becerilerimizi birlikte geliştirelim!
Hazır mısın? Başlayalım!
Daha büyük projeler üzerinde çalışırken bulunamayan rotalara dikkat etmek önemlidir. Bu rotalara sıklıkla 404 rotaları diyoruz çünkü sunucuda bir belge bulunmadığında 404 HTTP durum kodunu döndürüyorlar.
Bu arada, eğer bir kedi aşığıysanız http.cat adresine göz atmak hoşunuza gidebilir.
Şimdi, diğer rotaların hiçbiri tarayıcıdaki mevcut URL ile eşleşmediğinde tetiklenecek özel bir Rota oluşturmaya bakalım.
import {BrowserRouter, Routes, Route} from "react-router-dom"; function App() { return <BrowserRouter> <Routes> <Route path="/" element={<p>Landing page</p>}></Route> <Route path="/products" element={<p>Products page</p>}></Route> <Route path="*" element={<p>404 page</p>}></Route> </Routes> </BrowserRouter> }
Ana sayfaya /
erişirken kullanıcılar Açılış sayfasına yönlendirilecektir. /products
sayfasına gitmek onları Ürünler sayfasına yönlendirecektir. Ancak belirli bir rotaya karşılık gelmeyen başka bağlantılara erişilirse 404 sayfası görüntülenecektir.
Bu davranışın ardındaki neden, 404 sayfası için path özelliğinin *
olarak ayarlandığı özel bir <Route>
uygulanmasıdır. Bu konfigürasyon, React Router'ın başka hiçbir rota eşleştirilemediğinde yalnızca bu rotayı kullanmasını sağlar. 404 Rotasının spesifik yerleşimi önemsizdir ve onun ayrılmaz bir bileşeni olarak <Routes>...</Routes>
bölümü içinde herhangi bir yere yerleştirilebilir.
Uygulamaların rotaları pratik bir şekilde kullanmasının bir başka yolu da menüde o anda aktif olan sayfayı vurgulamaktır.
Ana Sayfa - Bu bağlantı kullanıcıyı ana sayfaya /
yönlendirir.
Hakkında - Bu bağlantı kullanıcıyı hakkında /about
sayfasına yönlendirir.
React Router ile kullanıcı /about
rotasındayken About
linkini otomatik olarak öne çıkarmak mümkün hale geliyor. Benzer şekilde, kullanıcı /
rotasındayken Ana Sayfa bağlantısını vurgulayabilirsiniz. En iyi yanı, bunu karmaşık koşul ifadelerine ihtiyaç duymadan başarabilmenizdir.
import {NavLink} from "react-router-dom"; function getClassName({isActive}) { if (isActive) { return "active"; // CSS class } } function App() { return <ul> <li> <NavLink to="/" className={getClassName}>Home</NavLink> </li> <li> <NavLink to="/about" className={getClassName}>About</NavLink> </li> </ul> }
Yukarıda gördüğünüz kodun active
sınıfın çalışması için biraz CSS'ye ihtiyacı var. Böylece, o anda aktif olan sayfanın menü bağlantısının kalın ve dikkat çekici görünmesini sağlayarak bunu geliştirebiliriz.
.active { font-weight: bold; }
NavLink
öğesinin className
özelliği, yalnızca bir dize yerine bir işlevi kabul etme esnekliğine sahiptir. Bir işlevi kullanmaya karar verdiğinizde ona parametre olarak bir nesne verilecek ve bu nesnenin üzerinde zaten ayarlanmış olan isActive
özelliği bulunacaktır. Fonksiyon içerisinde bu özelliğe kolaylıkla ulaşabilmek için parametre içerisine {isActive}
ekleyerek yıkım işlemini kullanıyoruz.
Daha sonra isActive
doğruluk değerine sahip olup olmadığını doğrulamaya devam ediyoruz. Eğer durum buysa, CSS sınıf adını active
döndüreceğiz.
React Router'daki geçerli yol NavLink
bileşeninin to
niteliğiyle eşleştiğinde isActive
işlevi bir boolean değeri olarak değerlendirecektir.
Sonuç olarak, React Router active
sınıfı karşılık gelen <NavLink />
öğesine sorunsuz bir şekilde dahil edecek ve onu mevcut aktif rota olarak gösterecektir.
Daha kısa bir yaklaşımı tercih ederseniz yukarıda belirtilen kodu yeniden düzenlemek için üçlü operatörü kullanabilirsiniz. Bu operatör, if/else ifadesini format: condition ? truthy expression : falsy expression
.
Üçlü operatörü pek kullanmıyorum çünkü çoğu zaman kodu daha az okunabilir hale getirebilir. Ancak bu durumda kullanılması kabul edilebilir.
function getClassName({isActive}) { if (isActive) { return "active"; } else { return ""; } }
function getClassName({isActive}) { return isActive ? "active" : ""; }
Return ifadesinin üçlü operatörün dışına yerleştirildiğinden emin olmanız yeterlidir. isActive
koşulu doğru olduğunda ?
"active"
yürütülecektir. Aksi takdirde :
den sonraki ifade ""
olarak yürütülür.
Artık getClassName
adında ayrı bir işlev tanımına olan ihtiyacı ortadan kaldırabiliriz. Bunun yerine şuna benzer bir ok işlevi kullanabiliriz: ({isActive}) => isActive ? "active" : ""
.
Bu değişikliğin okunmasının çok zor olduğunu düşünüyorsanız daha önce olduğu gibi ayrı bir işlevi kullanmaya devam edebilirsiniz.
import {NavLink} from "react-router-dom"; function App() { return <ul> <li> <NavLink to="/" className={({isActive}) => isActive ? "active" : ""}>Home</NavLink> </li> <li> <NavLink to="/about" className={({isActive}) => isActive ? "active" : ""}>About</NavLink> </li> </ul> }
Ah oğlum, neredeyse düşüncelerini duyabiliyorum!
Sojin, sen gittin ve DRY ilkesini çiğnedin, değil mi?
Bu sadece bir örnek. O kadar uğraşmaya gerek yok 😀
Her zamanki dostumuz Link
yerine NavLink
kullandığımı zaten fark etmiş olabilirsiniz. Ama merak etmeyin, nedenini açıklayayım. Görüyorsunuz, <Link />
bileşeni className
desteği için bir işlev tanımı kullanmanıza izin vermiyor. Evet, şaşırtıcı olabilir ama <Link />
ile çalışırken durum böyledir.
Gördüğüm yaygın hatalardan biri, genç React geliştiricilerinin bir <Link />
bileşeninin className
desteğindeki işlev tanımlarını kullanmaya çalışmasıdır ki bu da işe yaramamaktadır.
İlgilenirseniz bu konu hakkında bir makale yazabilirim. Sadece yorumlarda bana bildirin!
Belirli durumlarda, React uygulamanızdaki sayfaların yerini programlı olarak yeniden konumlandırmanız gerekebilir. Örneğin ziyaretçiyi belirli bir sayfaya yönlendirmek için bir istek gönderip yanıtını bekleyebilirsiniz.
/dashboard
yönlendirin.
Bu, kullanıcıyı programlı olarak yeni bir rotaya yönlendirmek için kullanabileceğiniz bir işlevi döndüren useNavigate()
kancasının kullanılmasını gerektirir.
Bir göz at:
import React, {useEffect} from "react"; import {useNavigate} from "react-router-dom"; function HelpPage() { const navigate = useNavigate(); useEffect(() => { const isLoggedIn = window.localStorage.getItem("isLoggedIn"); if (!isLoggedIn) { navigate("/login"); } }, []); return <h2>Help page</h2>; }
Bu örnekte, localStorage'ın isLoggedIn
anahtarına atanmış bir değere sahip olup olmadığını kontrol ediyoruz. Aksi takdirde, navigate("/login")
işlevini kullanarak kullanıcıyı /login
sayfasına yönlendireceğiz.
Çalışmasını sağlamak için, <BrowserRouter />
bileşeninin içine yerleştirilmiş bir bileşenin içinde useNavigate()
kancasını kullanmayı unutmayın. Aksi halde düzgün çalışmayacaktır.
Örneğin aşağıdaki örnek çalışmaz:
import React from "react"; import {BrowserRouter, useNavigate} from "react-router-dom"; function App() { // ❌ This breaks because the component was not wrapped by BrowserRouter, but its children are. const history = useNavigate(); return <BrowserRouter> {/* ... */} </BrowserRouter>; }
App()
bileşeninin içindeki useNavigate()
kancasını kullanmaya çalışıyorsanız küçük bir aksaklıkla karşılaşabilirsiniz. Bunun nedeni App()
bileşenini <BrowserRouter />
ile sarmalamadığınız sürece çalışmamasıdır.
Ama endişelenme!
İyi haber şu ki, App içindeki tüm alt bileşenler otomatik olarak <BrowserRouter />
tarafından sarılacak, böylece bu alt bileşenlerde useNavigate()
herhangi bir sorun yaşamadan mutlu bir şekilde kullanabilirsiniz.
Ancak gerçekten <App />
bileşeninde useNavigate()
işlevini kullanmanız gerekiyorsa, basit bir çözüm var. Yalnızca <App />
ı saran bir ana bileşen oluşturmanız ve <BrowserRouter />
öğesini bu ana bileşenin içine taşıdığınızdan emin olmanız gerekir. Bunu yaptıktan sonra, hazır olacaksınız ve <App />
bileşenindeki useNavigate()
işlevini istediğiniz gibi kullanabilirsiniz 💗
Web sitenizi erişilebilir hale getirmek söz konusu olduğunda bağlantılarınızın nasıl yapılandırıldığına dikkat etmek önemlidir. Bunu sağlamak için diğer yöntemler yerine <Link />
elemanlarının kullanılması tavsiye edilir.
Neden?
Bu öğeler otomatik olarak erişilebilirlik özellikleriyle bilinen <a>
etiketleri olarak işlenecektir.
Şimdi size dostane bir ipucu: normal <Link />
öğelerinizi useNavigate()
tarafından sağlanan .push()
yöntemiyle değiştirmekten kaçının. Bu yöntem yalnızca <Link />
öğesinin kullanılmasının mümkün olmadığı durumlarda kullanılmalıdır.
Genellikle bu, fetch()
işleminin sonucu gibi belirli bir mantığa dayalı olarak kullanıcıları programlı olarak yönlendirmeniz gerektiği zamandır.
React Router'ın sizi yeni bir adrese götürdüğü her defasında bir kod parçasını çalıştırmak isterseniz ne olur?
useLocation
kancasının yardımıyla bunu kolayca başarabilirsiniz. Ancak ayrıntılara dalmadan önce bunun kullanışlı olabileceği bazı senaryoları inceleyelim. En yaygın kullanım durumlarından biri, Google Analytics gibi analiz hizmetinize bir sayfa görüntüleme etkinliği göndermektir.
Ancak şunu belirtmekte fayda var ki Google Analytics 4 artık bu işi otomatik olarak yapıyor, yani bunu mutlaka sizin uygulamanıza gerek yok.
Bununla birlikte, useLocation
kancasını öğrenmek, bunun için başka amaçlar bulabileceğiniz için hala değerlidir. Örneğin, onu diğer kütüphaneler ve analiz hizmetleriyle entegre etmek veya ziyaret edilen rotalara göre belirli eylemleri yürütmek için kullanabilirsiniz.
İmkanlar sonsuzdur!
useLocation
kancası son derece kullanışlıdır çünkü size o anda kullanılmakta olan rota hakkında bilgi verir.
UseLocation kancasının nasıl kullanılacağına ilişkin kullanıcı dostu bir kılavuz:
import {BrowserRouter, Routes, Route, useLocation} from "react-router-dom"; import {createRoot} from "react-dom/client"; function App() { const location = useLocation(); console.log(location.pathname); return <Routes> {/* routes here... */} </Routes> } createRoot(document.querySelector("#react-root")).render(<BrowserRouter><App /></BrowserRouter>);
Artık rota bilgilerine konum değişkeni aracılığıyla erişebilirsiniz. Geçerli pathname
içeren bir nesnedir.
Kullanıcının şu anda hangi rotaya göz attığını bulmak için location.pathname
kullanmanız yeterlidir. Size /
, /about
veya kurduğunuz başka herhangi bir rota gibi bir şey verecektir.
useNavigate
kancasında olduğu gibi, kodunuzun <BrowserRouter />
tarafından sarılmış bir bileşenin içinde çalışmasının önemli olduğunu unutmayın. Aksi halde useLocation
kancası sihrini gerçekleştiremez.
Konum değiştiğinde, React Router'daki mevcut URL yoluna erişmek için useLocation
kancasını kullanabilirsiniz. Kodunuzu bir useEffect
kancasıyla sararak ve bağımlılığı location
olarak ayarlayarak, yeni bir URL'ye gezinme olduğunda belirli bir kod parçasını çalıştırabilirsiniz.
import React, {useEffect} from "react"; import {BrowserRouter, Routes, Route, useLocation} from "react-router-dom"; import {createRoot} from "react-dom/client"; function App() { const location = useLocation(); // run a piece of code on location change useEffect(() => { console.log(location.pathname); // send it to analytic, or do some conditional logic here }, [location]); return <Routes> {/* routes here... */} </Routes> } createRoot(document.querySelector("#react-root")).render(<BrowserRouter><App /></BrowserRouter>);
Kullanıcı navigasyon sırasında yeni bir rotaya geçtiğinde, useEffect
kancasının içindeki kod çalışacak ve işini yapacaktır. Temel olarak, konum nesnesinde bir değişiklik olduğunda belirli kodun yürütülmesini sağlamanın bir yoludur.
Özetlemek gerekirse, bu makale size React Router hakkında daha derin bir anlayış kazandırdı. Burada tartışılan özelliklerin tamamını kullanamayabilirsiniz. Yine de bunların farkında olmanız harika. Gelecekte benzer işlevleri birleştirmeye ihtiyaç duyarsanız tam olarak nereye bakmanız gerektiğini bilirsiniz. Bu nedenle, kolay referans olması için bu gönderiyi kaydettiğinizden veya yer imlerinize eklediğinizden emin olun. Ayrıca herhangi bir sorunuz varsa veya daha fazla yardıma ihtiyacınız olursa bana Twitter üzerinden ulaşmaktan çekinmeyin. Yardım etmek için buradayım!