React Router’da Rota Haritalandırma: Kapsamlı Bir Rehber
Giriş
Modern web uygulamaları, özellikle Single-Page Application (SPA) mimarisiyle geliştirilenler, kullanıcı deneyimini zenginleştirmek için dinamik ve akıcı bir navigasyon yapısına ihtiyaç duyar. Kullanıcıların farklı sayfalar arasında kesintisiz geçiş yapabilmesi, URL’nin uygulamanın mevcut durumunu yansıtması ve tarayıcının geri/ileri butonlarının beklendiği gibi çalışması, bir yönlendirme (routing) kütüphanesinin temel görevlerindendir. React ekosisteminde bu ihtiyacı en güçlü ve yaygın şekilde karşılayan kütüphane şüphesiz React Router’dır.
React Router, deklaratif (declarative) bir yaklaşımla, bileşen tabanlı bir şekilde rotaları tanımlamanıza olanak tanır. Bu sayede, uygulamanızın farklı bölümlerini URL’lerle eşleştirmek, dinamik veri yüklemek, kullanıcı yetkilendirmesi yapmak ve genel olarak uygulamanızın navigasyon akışını yönetmek oldukça kolaylaşır. Bu makale, React Router’ın temel kurulumundan başlayarak, rota tanımlama, dinamik rotalar, iç içe rotalar, programatik navigasyon, rota koruma ve gelişmiş yapılandırmalar gibi konuları derinlemesine inceleyerek, React Router ile rota haritalandırma konusunda kapsamlı bir rehber sunmayı amaçlamaktadır. Hem React Router v5 hem de daha güncel ve basitleştirilmiş v6 versiyonundaki yaklaşımlara değinilerek, aralarındaki temel farklar vurgulanacaktır.
React Router’a Giriş
React Router, bir React uygulamasında URL’yi bileşenlerle eşleştirmek için kullanılan standart bir kütüphanedir. Kullanıcının adres çubuğuna yazdığı URL’ye veya bir bağlantıya tıkladığında oluşan URL değişikliğine göre hangi React bileşeninin ekranda gösterileceğini belirler.
Temel Konseptler ve Neden React Router?
React Router’ın merkezinde birkaç anahtar bileşen ve konsept bulunur:
* Router: Uygulamanızın tamamını sarmalayan ve yönlendirme bağlamını sağlayan ana bileşendir (örneğin BrowserRouter).
* Route: Belirli bir URL yolunu (path) bir React bileşeniyle eşleştiren bileşendir.
* Link / NavLink: Kullanıcıların farklı rotalar arasında gezinmesini sağlayan deklaratif navigasyon bileşenleridir.
Routes (v6) / Switch (v5): Tanımlanmış Route bileşenlerini gruplayarak, mevcut URL ile eşleşen ilk* rotayı render etmeyi sağlayan bileşenlerdir.
React Router, bileşen tabanlı yapısıyla React’ın felsefesine mükemmel bir şekilde uyar. Deklaratif yapısı sayesinde, uygulamanızın navigasyonunu “nasıl” yapacağınızı değil, “ne” yapacağınızı tanımlarsınız. Bu, kodunuzu daha okunabilir, bakımı daha kolay ve hatalara karşı daha dirençli hale getirir.
Kurulum
React Router’ı projenize eklemek için npm veya yarn kullanabilirsiniz:
npm install react-router-dom
veya
yarn add react-router-dom
react-router-dom paketi, web uygulamaları için özel olarak tasarlanmış DOM bağlamalarını (BrowserRouter, Link vb.) içerir.
Temel Rota Tanımlama
React Router ile rota tanımlamanın ilk adımı, uygulamanızı bir router bileşeni ile sarmalamak ve ardından Route bileşenlerini kullanarak URL yollarını bileşenlerle eşleştirmektir.
Router Bileşenleri
React Router iki ana router bileşeni sunar:
* BrowserRouter: HTML5 History API’sini kullanarak tarayıcı geçmişini yönetir. URL’ler normal bir web sitesi gibi görünür (örneğin example.com/about). Genellikle SPA’lar için tercih edilen yöntemdir. Sunucunuzun, tüm istekleri uygulamanızın ana HTML dosyasına yönlendirecek şekilde yapılandırılması gerekir (client-side routing).
* HashRouter: URL’lerde hash (#) kullanır (örneğin example.com/#/about). Bu, sunucu yapılandırması gerektirmeyen daha basit bir yaklaşımdır, ancak URL’ler daha az estetik görünebilir ve SEO açısından bazı dezavantajları olabilir.
Çoğu modern React uygulamasında BrowserRouter tercih edilir. Uygulamanızın ana bileşenini (genellikle App.js veya index.js içindeki App bileşeni) bir BrowserRouter içine alarak yönlendirme bağlamını sağlarsınız:
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
);
Route Bileşeni
Route bileşeni, belirli bir URL yolu ile bir React bileşenini eşleştirmek için kullanılır.
* path prop’u: Eşleşecek URL yolunu belirtir.
* element prop’u (v6): Yol eşleştiğinde render edilecek React bileşenini alır. v5’te bu prop’lar component (bileşenin kendisini alır) veya render (bir fonksiyon alır ve render edilecek JSX’i döndürür) idi. v6, bu karmaşıklığı ortadan kaldırarak yalnızca element prop’unu kullanır.
Örnek kullanım:
// App.js
import React from 'react';
import { Routes, Route } from 'react-router-dom';
import HomePage from './pages/HomePage';
import AboutPage from './pages/AboutPage';
import ContactPage from './pages/ContactPage';
function App() {
return (
} />
} />
} />
);
}
export default App;
Routes Bileşeni (v6) / Switch Bileşeni (v5)
Uygulamanızda birden fazla Route tanımlandığında, mevcut URL ile birden fazla rota eşleşebilir. Örneğin, /about yolu hem path="/" ile hem de path="/about" ile eşleşebilir. Bu durumu önlemek ve sadece en iyi eşleşen tek bir rotayı render etmek için Routes (v6) veya Switch (v5) bileşenleri kullanılır.
* Routes (v6): Routes bileşeni, çocukları olarak tanımlanan tüm Route‘ları tarar ve URL ile eşleşen ilk Route‘u render eder. v6’da exact prop’una artık ihtiyaç yoktur; Routes varsayılan olarak en spesifik eşleşmeyi seçer.
* Switch (v5): Aynı işlevi görürdü ancak exact prop’u olmadan, / yolu /about yolundan önce tanımlanırsa, /about yerine / yolunun bileşeni render edilirdi. Bu nedenle v5’te exact prop’u sıkça kullanılırdı: .
Routes bileşeninin kullanılması, uygulamanızın navigasyon mantığını daha öngörülebilir ve kontrol edilebilir hale getirir.
Dinamik Rotlar ve Parametreler
Çoğu zaman, bir uygulamanın aynı sayfa düzenini kullanarak farklı içerikleri göstermesi gerekir. Örneğin, bir e-ticaret sitesinde her ürünün kendi detay sayfası vardır, ancak bu sayfaların yapısı genellikle aynıdır. Bu gibi durumlar için React Router, dinamik rotaları ve URL parametrelerini destekler.
URL Parametreleri
URL parametreleri, rotanın bir parçası olarak değişken verileri yakalamak için kullanılır. path prop’unda iki nokta üst üste (:) ile belirtilirler.
Örnek: path="/products/:id" burada :id bir parametredir.
Bu parametrelere, bileşen içinde useParams hook’u (v6) aracılığıyla erişilebilir.
import React from 'react';
import { useParams } from 'react-router-dom';
function ProductDetailPage() {
const { id } = useParams(); // URL'den id parametresini alır
// id'yi kullanarak ürün verilerini çekme veya gösterme
return (
Ürün ID: {id}
{/ Ürün bilgilerini burada göster /}
);
}
export default ProductDetailPage;
Eğer URL /products/123 ise, id değeri 123 olacaktır.
Query Parametreleri
URL parametrelerinden farklı olarak, query parametreleri URL’nin sonuna soru işareti (?) ile eklenir ve anahtar-değer çiftleri şeklinde veri taşır (örneğin ?category=electronics&sort=price). Bunlar genellikle filtreleme, arama veya sayfalama gibi isteğe bağlı verileri iletmek için kullanılır.
v6’da useSearchParams hook’u ile query parametrelerine erişilebilir ve yönetilebilir:
import React from 'react';
import { useSearchParams } from 'react-router-dom';
function SearchResultsPage() {
const [searchParams, setSearchParams] = useSearchParams();
const query = searchParams.get('q'); // URL'den 'q' parametresini alır
const category = searchParams.get('category');
// Arama sonuçlarını query ve category'ye göre gösterme
return (
Arama sorgusu: {query || 'Yok'}
Kategori: {category || 'Tümü'}
);
}
export default SearchResultsPage;
setSearchParams fonksiyonu ile query parametreleri programatik olarak güncellenebilir.
İç İçe Rotlar (Nested Routes)
Büyük ve karmaşık uygulamalarda, bir ana sayfanın (parent route) altında birden fazla alt sayfa (child routes) bulunması yaygındır. Örneğin, bir kullanıcı paneli (/dashboard) altında ayarlar (/dashboard/settings), profil (/dashboard/profile) veya mesajlar (/dashboard/messages) gibi alt bölümler olabilir. Bu yapıya iç içe rotalar denir ve React Router bunu kolayca yönetmenizi sağlar.
V6 Yaklaşımı
React Router v6, iç içe rotaları tanımlama ve render etme şeklini önemli ölçüde basitleştirmiştir. Artık parent Route içinde alt Route‘ları tanımlayabilir ve parent bileşenin neresinde alt rotanın içeriğinin render edileceğini Outlet bileşeni ile belirtebilirsiniz.
// App.js
import React from 'react';
import { Routes, Route } from 'react-router-dom';
import HomePage from './pages/HomePage';
import DashboardLayout from './pages/DashboardLayout'; // Parent bileşen
import DashboardSettings from './pages/DashboardSettings';
import DashboardProfile from './pages/DashboardProfile';
function App() {
return (
} />
}>
{/ İç içe rotalar burada tanımlanır /}
} /> {/ Göreceli yol /}
} /> {/ Göreceli yol /}
Dashboard Ana Sayfa} /> {/ '/dashboard' için varsayılan alt rota /}
);
}
export default App;
// pages/DashboardLayout.js
import React from 'react';
import { Outlet, Link } from 'react-router-dom';
function DashboardLayout() {
return (
Dashboard
{/ Alt rotanın içeriği burada render edilecek /}
);
}
export default DashboardLayout;
Bu örnekte, /dashboard/settings ve /dashboard/profile rotaları DashboardLayout bileşeninin içinde render edilir. Outlet bileşeni, parent rotanın alt rotaları için bir yer tutucu görevi görür. index prop’u, parent rotanın tam olarak eşleştiğinde (örneğin /dashboard) gösterilecek varsayılan alt rotayı belirtir. Link bileşenindeki to prop’unda göreceli yollar (settings, profile) kullanıldığına dikkat edin; bu, parent rotanın yoluna göre otomatik olarak çözümlenir.
Programatik Navigasyon
Kullanıcıların bir bağlantıya tıklamasıyla (deklaratif navigasyon) rotalar arasında gezinmek yaygın olsa da, bazen bir form gönderimi, bir API çağrısı sonrası veya belirli bir koşulun sağlanması gibi durumlarda programatik olarak yönlendirme yapmak gerekebilir.
Link ve NavLink
Bu bileşenler, kullanıcıların uygulamanız içinde gezinmesi için standart HTML etiketinin React Router versiyonlarıdır. Yeniden yükleme yapmadan SPA içinde gezinmeyi sağlarlar.
* Link: Temel bir bağlantı sağlar.
* NavLink: Link‘in tüm özelliklerine ek olarak, mevcut URL ile eşleştiğinde “aktif” stil veya sınıf uygulama yeteneğine sahiptir. Bu, navigasyon menülerinde hangi öğenin aktif olduğunu vurgulamak için kullanışlıdır.
import { Link, NavLink } from 'react-router-dom';
function Navbar() {
return (
);
}
v6’da className ve style prop’larına bir fonksiyon geçirerek isActive durumuna göre dinamik stil uygulayabilirsiniz.
useNavigate Hook’u (v6) / useHistory Hook’u (v5)
Programatik navigasyon için React Router v6’da useNavigate hook’u kullanılır. Bu hook, bir fonksiyon döndürür ve bu fonksiyonu çağırarak kullanıcıyı belirli bir rotaya yönlendirebilirsiniz.
import React from 'react';
import { useNavigate } from 'react-router-dom';
function LoginForm() {
const navigate = useNavigate();
const handleSubmit = (event) => {
event.preventDefault();
// Form doğrulama ve API çağrısı
const isAuthenticated = true; // Varsayımsal doğrulama sonucu
if (isAuthenticated) {
navigate('/dashboard', { replace: true }); // Kullanıcıyı dashboard'a yönlendir, geçmişte yerine koy
} else {
alert('Kullanıcı adı veya şifre yanlış!');
}
};
return (
);
}
export default LoginForm;
navigate fonksiyonu, ilk argüman olarak bir yol string’i veya bir sayı (geri gitmek için -1, ileri gitmek için 1) alabilir. İkinci argüman olarak bir options objesi alabilir; örneğin replace: true ile mevcut girişin tarayıcı geçmişinde değiştirilmesini sağlayabilirsiniz, bu da kullanıcının geri butonuna bastığında önceki sayfaya değil, daha önceki bir sayfaya gitmesini sağlar (giriş sayfasından sonra dashboard’a yönlendirmede sıkça kullanılır).
Rota Koruma (Protected Routes)
Birçok uygulamada, belirli sayfalara erişimin kullanıcı girişi (authentication) veya yetkilendirme (authorization) gerektirmesi gibi durumlar vardır. React Router, bu “korumalı rotaları” uygulamak için esnek bir yapı sunar.
Genel yaklaşım, özel bir ProtectedRoute bileşeni oluşturmaktır. Bu bileşen, kullanıcının kimlik doğrulama durumunu kontrol eder ve eğer yetkili değilse, onu giriş sayfasına veya başka bir genel sayfaya yönlendirir.
import React from 'react';
import { Route, Navigate } from 'react-router-dom';
import { useAuth } from './AuthContext'; // Varsayımsal bir kimlik doğrulama bağlamı
function ProtectedRoute({ children }) {
const { isAuthenticated } = useAuth(); // Kullanıcının giriş yapıp yapmadığını kontrol eder
if (!isAuthenticated) {
// Eğer kullanıcı giriş yapmamışsa, giriş sayfasına yönlendir
return ;
}
// Kullanıcı giriş yapmışsa, çocuk bileşenleri render et
return children;
}
// App.js içinde kullanımı:
//
// } />
// } />
//
//
//
// } />
//
Bu örnekte, ProtectedRoute bileşeni children prop’u aracılığıyla render edilecek bileşeni alır. useAuth hook’u (kendi oluşturduğunuz bir bağlamdan gelebilir) kullanıcının oturum açmış olup olmadığını kontrol eder. Eğer oturum açmamışsa, Navigate bileşeni kullanıcıyı /login rotasına yönlendirir ve tarayıcı geçmişindeki mevcut girişi değiştirir (replace). Aksi takdirde, korunan bileşen (DashboardPage gibi) render edilir.
404 Not Found Sayfaları
Kullanıcının var olmayan bir URL’ye gitmeye çalıştığı durumlarda, genellikle bir “404 Sayfa Bulunamadı” sayfası göstermek istenir. React Router’da bu, Routes (v6) veya Switch (v5) içindeki tüm rotalardan sonra bir wildcard (*) yolu tanımlanarak kolayca yapılabilir. Wildcard yolu, diğer tüm yollar eşleşmediğinde devreye girer.
// App.js
import React from 'react';
import { Routes, Route } from 'react-router-dom';
import HomePage from './pages/HomePage';
import AboutPage from './pages/AboutPage';
import NotFoundPage from './pages/NotFoundPage';
function App() {
return (
} />
} />
{/ Tüm diğer rotalar eşleşmediğinde bu rota devreye girer /}
} />
);
}
export default App;
NotFoundPage bileşeni, kullanıcının aradığı sayfanın bulunamadığını bildiren bir mesaj içerecektir.
Gelişmiş Rota Yapılandırmaları ve İpuçları
React Router, büyük ve karmaşık uygulamalar için daha da optimize edilmiş yapılandırmalar ve performans iyileştirmeleri sunar.
Rota Konfigürasyonunu Harici Bir Dosyada Yönetme
Uygulamanız büyüdükçe, tüm rotaları App.js içinde tanımlamak karmaşık hale gelebilir. Rota tanımlarını ayrı bir JavaScript dosyasında (örneğin routes.js) bir dizi obje olarak tutmak, okunabilirliği ve yönetilebilirliği artırır.
// routes.js
import HomePage from './pages/HomePage';
import AboutPage from './pages/AboutPage';
import ProductDetailPage from './pages/ProductDetailPage';
import NotFoundPage from './pages/NotFoundPage';
const routes = [
{
path: '/',
element: ,
exact: true, // v5'ten kalan bir alışkanlık, v6'da gereksiz
},
{
path: '/about',
element: ,
},
{
path: '/products/:id',
element: ,
},
{
path: '*',
element: ,
},
];
export default routes;
// App.js
import React from 'react';
import { Routes, Route } from 'react-router-dom';
import appRoutes from './routes'; // Rota yapılandırmasını import et
function App() {
return (
{appRoutes.map((route, index) => (
))}
);
}
export default App;
Bu yaklaşım, rotaları daha modüler hale getirir ve dinamik olarak oluşturmanıza olanak tanır.
Code Splitting (Kod Bölünmesi) ve Lazy Loading
Büyük uygulamalarda, tüm bileşenleri başlangıçta yüklemek uygulamanın açılış süresini uzatabilir. React’ın React.lazy ve Suspense özellikleri ile React Router’ı birleştirerek, yalnızca bir rota ziyaret edildiğinde ilgili bileşenleri dinamik olarak yükleyebilirsiniz. Bu, “lazy loading” veya “code splitting” olarak bilinir ve performansı önemli ölçüde artırır.
import React, { lazy, Suspense } from 'react';
import { Routes, Route } from 'react-router-dom';
const HomePage = lazy(() => import('./pages/HomePage'));
const AboutPage = lazy(() => import('./pages/AboutPage'));
const ProductDetailPage = lazy(() => import('./pages/ProductDetailPage'));
const NotFoundPage = lazy(() => import('./pages/NotFoundPage'));
function App() {
return (
Yükleniyor...