Sıfırdan İleriye React serisinin yeni bir konusuna hoş geldiniz. En son Redux ile http istekleri atarak api çağırma işlemlerini görmüştük.
Bugün de react içinde bulunan güzel bir paket olan React Router'i öğreneceğiz. React Router bize belirttiğimiz compenente yeni bir link ekleyip sayfa oluşturmasını sağlıyor.
Ne demek bu der gibiyseniz bir web site düşünün Trendyol, HepsiBurada vb. hiç fark etmez sitenin ne olduğu. Orada bir sürü ürün var ve ürünün detayların gittiğimizde domain/ürünler/ürünad+ürünid gibi bir şeyler karşılaşabiliriz. Daha basit olarak tht profil linkine bakın.
domain + uye + nick + kaçıncı üye şeklinde oluşuyor linki. Biz de React Router ile compenentleri yönlendireceğiz. Mesela lokal adresimize bir sayfa ekleyeceğiz ve bunu React Router ile yönlendirip kullanacağız.
Localhost:3000 bizim ana local domainimiz. Buraya /about ekleyip about compenentine şu şekilde ulaşabileceğiz. Localhost:3000/about
Teorik olarak konu bu kadar. Şimdi pratikte şu paketi daha iyi anlayıp yönlendirme işlemlerine bakalım.
İlk olarak paketi indirmemiz lazım bu yüzden npm ile paketi kuralım.
Terminale bunu yazdıktan sonra biraz bekleyin ve paket inecektir. Artık paketin içindeki özellikleri kullanarak yönlendirme işlemlerimizi yapabileceğiz.
İlk olarak ana componente bir sırasız liste oluşturacağım ve bunları css ile düzenlemeyeceğim konumuz css değil ama siz isterseniz css ile navbar tarzı bir şey yapabilirsiniz.
Bugün de react içinde bulunan güzel bir paket olan React Router'i öğreneceğiz. React Router bize belirttiğimiz compenente yeni bir link ekleyip sayfa oluşturmasını sağlıyor.
Ne demek bu der gibiyseniz bir web site düşünün Trendyol, HepsiBurada vb. hiç fark etmez sitenin ne olduğu. Orada bir sürü ürün var ve ürünün detayların gittiğimizde domain/ürünler/ürünad+ürünid gibi bir şeyler karşılaşabiliriz. Daha basit olarak tht profil linkine bakın.
Kod:
https://www.turkhackteam.org/uye/darks0ldier.888402/
domain + uye + nick + kaçıncı üye şeklinde oluşuyor linki. Biz de React Router ile compenentleri yönlendireceğiz. Mesela lokal adresimize bir sayfa ekleyeceğiz ve bunu React Router ile yönlendirip kullanacağız.
Localhost:3000 bizim ana local domainimiz. Buraya /about ekleyip about compenentine şu şekilde ulaşabileceğiz. Localhost:3000/about
Teorik olarak konu bu kadar. Şimdi pratikte şu paketi daha iyi anlayıp yönlendirme işlemlerine bakalım.
İlk olarak paketi indirmemiz lazım bu yüzden npm ile paketi kuralım.
Kod:
npm i react-router-dom
Terminale bunu yazdıktan sonra biraz bekleyin ve paket inecektir. Artık paketin içindeki özellikleri kullanarak yönlendirme işlemlerimizi yapabileceğiz.
İlk olarak ana componente bir sırasız liste oluşturacağım ve bunları css ile düzenlemeyeceğim konumuz css değil ama siz isterseniz css ile navbar tarzı bir şey yapabilirsiniz.
JavaScript:
function App() {
return (
<div>
<div>
<ul>
<li>Ana Sayfa</li>
<li>Ürünüler</li>
<li>Kariyer</li>
<li>Hakkımızda</li>
<li>İletişim</li>
</ul>
</div>
</div>
)
}
export default App;
Şimdi ben her bir li etiket için ayrı dosya açacağım ki elemana tıkladığımda o sayfaya gideyim. İçlerini doldurmayacağım sadece yönlendirme işlemleri için kullanacağız daha sonra iki adet router için dosya oluşturacağız. Bunlardan biri layout diğeri ise router olacak. Bu iki dosyayı oluşturup içlerini dolduracağız.
Layout dediğimiz dosyada projenin temel düzenini sağlayıp navigasyon işlemlerini yaparız.
Kod:
import { Outlet, Link } from "react-router-dom";
function Layout() {
return (
<div>
<Link to="/">Ana Sayfa</Link>
<Link to="/urunler">Ürünler</Link>
<Link to="/kariyer">Kariyer</Link>
<Link to="/hakkimizda">Hakkımızda</Link>
<Link to="/iletisim">İletişim</Link>
<Outlet />
</div>
)
}
export default Layout
Link to ile navigasyon işlemlerini yaptık outlet kısmı ise nested dediğimiz iç içe yapılar için kullanılır. Mesela ürünler sayfası içinde iki adet daha sayfa oluşturalım. Mantık şöyle olacaktır.
Ürünler -> Kalem & Kitap
Kullanıcının seçeceği seçeneğe göre Ürünler -> kalem sayfası veya Ürünler -> kitap sayfası
İç içe yapılar yani nested deriz bu duruma. Outlet bu gibi işlemlerde kullanılır. Şimdilik layout sayfası bu kadar şimdi router sayfasını dolduralım.
JavaScript:
import React from 'react'
import { Routes, Route } from 'react-router-dom';
import AnaSayfa from '../AnaSayfa';
import Hakkimizda from '../Hakkimizda';
import Iletisim from '../Iletisim';
import Kariyer from '../Kariyer';
function Router() {
return (
<Routes>
<Route path="/" element={<AnaSayfa />} />
<Route path="hakkimizda" element={<Hakkimizda />} />
<Route path="iletisim" element={<Iletisim />} />
<Route path="kariyer" element={<Kariyer />} />
<Route path="urunler" element={<Urunler />} />
</Routes>
)
}
export default Router
Routes ile konteynır gibi route etiketlerini kaplıyoruz. Route path ile yönlendirilecek linki yazıyoruz element kısmı ise yönlendirilecek olan dosya oluyor. Zaten bu dosyaları yukarıda görüldüğü gibi import ediyoruz.
Şimdi nested yapılar için tekrar layout sayfasına diğer elemanları tanımladığımız gibi kitap ve kalem sayfaları oluşturup yazacağım.
JavaScript:
import { Outlet, Link } from "react-router-dom";
function Layout() {
return (
<div>
<Link to="/">Ana Sayfa</Link>
<Link to="/urunler">Ürünler</Link>
<Link to="/kariyer">Kariyer</Link>
<Link to="/hakkimizda">Hakkımızda</Link>
<Link to="/iletisim">İletişim</Link>
<Link to="/kalem">Kalem</Link>
<Link to="/kitap">Kitap</Link>
<Outlet />
</div>
)
}
export default Layout
Aynı şekilde router sayfasını da güncelleyeceğim ek olarak olmayan linkler için bir hata sayfası da yapalım. Mesela bizim projemizde abc linki olmayacak kullanıcı abc yazınca otomatik olarak böyle bir sayfa yok compenentine gitsin.
JavaScript:
import React from 'react'
import { Routes, Route } from 'react-router-dom';
import AnaSayfa from '../AnaSayfa';
import Hakkimizda from '../Hakkimizda';
import Iletisim from '../Iletisim';
import Kariyer from '../Kariyer';
import Kitap from '../Kitap';
import Kalem from '../Kalem';
import Bulunamadi from '../Bulunamadi';
function Router() {
return (
<Routes>
<Route path="/" element={<AnaSayfa />} />
<Route path="hakkimizda" element={<Hakkimizda />} />
<Route path="iletisim" element={<Iletisim />} />
<Route path="kariyer" element={<Kariyer />} />
<Route path="urunler" element={<Urunler />}>
<Route path="kalem" element={<Kalem />} />
<Route path="kitap" element={<Kitap />} />
</Route>
<Route path="*" element={<Bulunamadi />} />
</Routes>
)
}
export default Router
Urunler olan route içine iki adet iç içe yapı oluşturduk. Bu şekilde nested yapıyı da yönlendirdik ek olarak en sonda yönlendirme işleminin yoluna yıldız dedik bu olmayan sayfalarda devreye girecek olan yönlendirme işlemidir.
Şimdi yönlendirme ve navigasyon işlemlerini yaptık main sayfasına bunu bildirelim ki projenin her yerinde kullanalım. Mantık aynı redux toolkit gibi olacak.
JavaScript:
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.jsx'
import { BrowserRouter } from 'react-router-dom'
import Router from './Router/Router.jsx'
createRoot(document.getElementById('root')).render(
<BrowserRouter>
<App />
<Router />
</BrowserRouter>
)
BrowerRouter direkt router paketi içinde gelen bir özelliktir. App altındaki Router ise bizim oluşturduğumuz yönlendirme işlemlerini yapan dosyadır.
Şimdi useNavigate adı verilen bir hook var. Bu hook react router dom içinde geliyor. Bu hooku alıp yönlendirme işlemlerinde final dokunşları yapacağız. Kullanıcı iletişim listesine tıkladığında iletişim sayfasına gidecek mesela. Şimdi bunun için ana sayfaya geri dönüp useNavigate import edip kullanalım. Daha sonra aynı şeyi ürünler sayfasında yapacağız çünkü biliyorsunuz orada nested yapımız mevcut onları da yönlendirme işlemleri yapmıştık.
JavaScript:
import { useNavigate } from "react-router-dom";
function App() {
const navigate = useNavigate();
return (
<div>
<div>
<ul style={{ cursor: 'pointer' }}>
<li onClick={() => navigate("/")}>Ana Sayfa</li>
<li onClick={() => navigate("/urunler")}>Ürünüler</li>
<li onClick={() => navigate("/kariyer")}>Kariyer</li>
<li onClick={() => navigate("/hakkimizda")} >Hakkımızda</li>
<li onClick={() => navigate("/iletisim")}>İletişim</li>
</ul>
</div>
</div>
)
}
export default App;
JavaScript:
import React from 'react'
import { useNavigate } from 'react-router-dom'
function Urunler() {
const navigate = useNavigate();
return (
<div>Urunler
<ul>
<li onClick={() => navigate("kalem")}>Kalem</li>
<li onClick={() => navigate("kitap")}>kitap</li>
</ul>
</div>
)
}
export default Urunler
Sırasıyla navigate hooklarını da ekledik. Şimdi uygulama çalışıyor mu deneyelim.
Görüldüğü üzere şu an anasaydayız. Link kısmını da kontrol ederseniz bunu görebilirsiniz. Şimdi anasayfa listesini tıklarsam yine aynı sayfada kalacağız. Ürünler kısmına tıklıyorum bu yüzden.
linkimiz http://localhost:5174/urunler oldu ayrıca ürünler compenenti içeriğine ulaştık burada kalem ve kitap listesi vardı bunlardan birine rastgele tıklıyorum.
http://localhost:5174/urunler/kalem linkimiz nested yapıdan dolayı bu şekile dönüştü. Tabi ki kalem dosyasının içeriği boş olduğu için sayfa içeriği değişmedi.
Şimdi İletişim kısmına tıklayalım.
http://localhost:5174/iletisim linkine ulaştık. Bu sayede hakkımızda compenenti içeriğini görüntülüyoruz. Bunları sırayla deneyebilirsiniz ben konuyu uzatmamak adına adresi bulunmayan bir sayfaya gitmeye çalışacağım bakalım bu durumda ne olacak.
http://localhost:5174/boylebirsayfavarmi adresini tanımlamadığımız için hata durumları için tanımladığımız compenente bizi yönlendirdi.
Ek olarak her sayfa değiştiğinde listemiz görünüyordu bunu engellemenin yolu var mı ?
Tabi ki var ben bu listeyi app dosyasında yani ana react sayfasında yaptığım için her seferinde liste elemanları karşımıza çıkıyor. Bunu engellemek için yönlendirilecek elemanların listesini başka bir compenentte tanımlayın.
Peki elimde birden çok liste elemanı var tek tek hepsini onclick özelliğini tanımlayıp navigate hookunu mu kullanmalıyım ?
Hayır, örneğin bir navbar yapıyorsunuz listenin elemanlarını bir diziye alın örneğin
JavaScript:
navbarElemanları = [anasayfa,hakkımzda,kariyer,....];
Kod:
Daha sonra yazdırmak için map fonksiyonu ile tüm dizi elemanlarını yazdırın. Böylece görünüm bakımından navbar olacaktır. Sıra onclick özelliğini navigate hookuna bağlamak kaldı. Bu durumda maple dönerken onclick özelliği ekleyin otomatik olarak tüm dizi elemanlarına onclick eklenecektir. navigate kullanmak için ise map içinde tanımlanan item değişkeni olarak yazın. Yani :
JavaScript:
navbarElemanları.map((elemanlar,index)=>{
Örnek olarak bu şekilde tek tek yazmak yerine tüm elemanlara tek bir işlemle onclick + hook ekleyebilirisiniz.
Peki bir api çektik ve her api farklı bunlara fiziki olarak hook ekleyemeyiz ne yapacağız ?
Bu durumda ise api dokümantasyonu okumakta fayda var. Mesela şu şekilde yapabiliriz.
JavaScript:
<Route path="/product/:query" element={<ProductDetails />} />
Buradaki product hali hazırda bir compenenti temsil ediyor. :query ise kullanıcının yazdığı sorguya göre değişiyor. Seri sonunda yapacağım projede burayı daha iyi anlayacağız.
Peki bazen yönlendiricileri gizlemek istersem ne olacak ?
Güzel bir soru, mesela e-ticaret sitesi yaparken kullanıcı kayıt veya giriş yapamadan kendi sayfasını görmemesi lazım bu gibi durumlarda Private Route denilen özel yönlendirme kullanılır. Bu bir sonraki konunun içeriği olacağı için şimdilik konuyu burada bitirelim. Bir sonraki konuda Private Route ve useContext hook'unu öğreneceğiz. Diğer konuda görüşmek üzere.



