Jelajahi pola navigasi esensial dengan React Router v6. Pelajari rute deklaratif, rute dinamis, navigasi terprogram, rute bersarang, dan strategi pemuatan data untuk membangun aplikasi web yang tangguh dan ramah pengguna.
React Router v6: Menguasai Pola Navigasi untuk Aplikasi Web Modern
React Router v6 adalah pustaka routing yang kuat dan fleksibel untuk aplikasi React. Ini memungkinkan Anda membuat aplikasi halaman tunggal (SPA) dengan pengalaman pengguna yang mulus dengan mengelola navigasi tanpa memuat ulang seluruh halaman. Postingan blog ini akan membahas pola navigasi esensial menggunakan React Router v6, memberi Anda pengetahuan dan contoh untuk membangun aplikasi web yang tangguh dan ramah pengguna.
Memahami Konsep Inti React Router v6
Sebelum mendalami pola-pola spesifik, mari kita tinjau beberapa konsep fundamental:
- Routing Deklaratif: React Router menggunakan pendekatan deklaratif, di mana Anda mendefinisikan rute Anda sebagai komponen React. Ini membuat logika routing Anda jelas dan mudah dikelola.
- Komponen: Komponen inti meliputi
BrowserRouter
,HashRouter
,MemoryRouter
,Routes
, danRoute
. - Hooks: React Router menyediakan hooks seperti
useNavigate
,useLocation
,useParams
, danuseRoutes
untuk mengakses informasi routing dan memanipulasi navigasi.
1. Routing Deklaratif dengan <Routes>
dan <Route>
Fondasi dari React Router v6 terletak pada routing deklaratif. Anda mendefinisikan rute Anda menggunakan komponen <Routes>
dan <Route>
. Komponen <Routes>
berfungsi sebagai wadah untuk rute Anda, dan komponen <Route>
mendefinisikan rute spesifik dan komponen yang akan dirender saat rute tersebut cocok dengan URL saat ini.
Contoh: Konfigurasi Rute Dasar
Berikut adalah contoh dasar pengaturan rute untuk aplikasi sederhana:
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Home from "./pages/Home";
import About from "./pages/About";
import Contact from "./pages/Contact";
function App() {
return (
} />
} />
} />
);
}
export default App;
Dalam contoh ini, kita mendefinisikan tiga rute:
/
: Merender komponenHome
./about
: Merender komponenAbout
./contact
: Merender komponenContact
.
Komponen BrowserRouter
mengaktifkan routing berbasis riwayat browser. React Router mencocokkan URL saat ini dengan rute yang ditentukan dan merender komponen yang sesuai.
2. Rute Dinamis dengan Parameter URL
Rute dinamis memungkinkan Anda membuat rute yang dapat menangani nilai yang berbeda di URL. Ini berguna untuk menampilkan konten berdasarkan pengidentifikasi unik, seperti ID produk atau ID pengguna. React Router v6 menggunakan simbol :
untuk mendefinisikan parameter URL.
Contoh: Menampilkan Detail Produk
Misalkan Anda memiliki aplikasi e-commerce dan ingin menampilkan detail untuk setiap produk berdasarkan ID-nya. Anda dapat mendefinisikan rute dinamis seperti ini:
import { BrowserRouter, Routes, Route, useParams } from "react-router-dom";
function ProductDetails() {
const { productId } = useParams();
// Ambil detail produk berdasarkan productId
// ...
return (
Detail Produk
ID Produk: {productId}
{/* Tampilkan detail produk di sini */}
);
}
function App() {
return (
} />
);
}
export default App;
Dalam contoh ini:
/products/:productId
mendefinisikan rute dinamis di mana:productId
adalah parameter URL.- Hook
useParams
digunakan untuk mengakses nilai parameterproductId
di dalam komponenProductDetails
. - Anda kemudian dapat menggunakan
productId
untuk mengambil detail produk yang sesuai dari sumber data Anda.
Contoh Internasionalisasi: Menangani Kode Bahasa
Untuk situs web multibahasa, Anda mungkin menggunakan rute dinamis untuk menangani kode bahasa:
} />
Rute ini akan cocok dengan URL seperti /en/about
, /fr/about
, dan /es/about
. Parameter lang
kemudian dapat digunakan untuk memuat sumber daya bahasa yang sesuai.
3. Navigasi Terprogram dengan useNavigate
Meskipun routing deklaratif bagus untuk tautan statis, Anda sering kali perlu menavigasi secara terprogram berdasarkan tindakan pengguna atau logika aplikasi. React Router v6 menyediakan hook useNavigate
untuk tujuan ini. useNavigate
mengembalikan fungsi yang memungkinkan Anda menavigasi ke rute yang berbeda.
Contoh: Mengalihkan Setelah Pengiriman Formulir
Katakanlah Anda memiliki pengiriman formulir dan ingin mengarahkan pengguna ke halaman sukses setelah formulir berhasil dikirim:
import { useNavigate } from "react-router-dom";
function MyForm() {
const navigate = useNavigate();
const handleSubmit = async (event) => {
event.preventDefault();
// Kirim data formulir
// ...
// Alihkan ke halaman sukses setelah pengiriman berhasil
navigate("/success");
};
return (
);
}
export default MyForm;
Dalam contoh ini:
- Kita menggunakan hook
useNavigate
untuk mendapatkan fungsinavigate
. - Setelah formulir berhasil dikirim, kita memanggil
navigate("/success")
untuk mengarahkan pengguna ke rute/success
.
Meneruskan State Selama Navigasi
Anda juga dapat meneruskan state bersamaan dengan navigasi menggunakan argumen kedua untuk navigate
:
navigate("/confirmation", { state: { orderId: "12345" } });
Ini memungkinkan Anda untuk meneruskan data ke komponen target, yang dapat diakses menggunakan hook useLocation
.
4. Rute Bersarang dan Tata Letak
Rute bersarang memungkinkan Anda membuat struktur routing hierarkis, di mana satu rute bersarang di dalam rute lain. Ini berguna untuk mengorganisir aplikasi kompleks dengan beberapa tingkat navigasi. Ini membantu dalam membuat tata letak di mana elemen UI tertentu selalu ada di seluruh bagian aplikasi.
Contoh: Bagian Profil Pengguna
Katakanlah Anda memiliki bagian profil pengguna dengan rute bersarang untuk menampilkan informasi profil, pengaturan, dan pesanan pengguna:
import { BrowserRouter, Routes, Route, Link } from "react-router-dom";
function Profile() {
return (
Profil Pengguna
-
Informasi Profil
-
Pengaturan
-
Pesanan
} />
} />
} />
);
}
function ProfileInformation() {
return Komponen Informasi Profil
;
}
function Settings() {
return Komponen Pengaturan
;
}
function Orders() {
return Komponen Pesanan
;
}
function App() {
return (
} />
);
}
export default App;
Dalam contoh ini:
- Rute
/profile/*
cocok dengan URL apa pun yang dimulai dengan/profile
. - Komponen
Profile
merender menu navigasi dan komponen<Routes>
untuk menangani rute bersarang. - Rute bersarang mendefinisikan komponen yang akan dirender untuk
/profile/info
,/profile/settings
, dan/profile/orders
.
Tanda *
di rute induk sangat penting; ini menandakan bahwa rute induk harus cocok dengan sub-path apa pun, memungkinkan rute bersarang untuk dicocokkan dengan benar di dalam komponen Profile
.
5. Menangani Error "Not Found" (404)
Sangat penting untuk menangani kasus di mana pengguna menavigasi ke rute yang tidak ada. React Router v6 membuat ini mudah dengan rute catch-all.
Contoh: Mengimplementasikan Halaman 404
import { BrowserRouter, Routes, Route, Link } from "react-router-dom";
function NotFound() {
return (
404 - Tidak Ditemukan
Halaman yang Anda cari tidak ada.
Kembali ke beranda
);
}
function App() {
return (
} />
} />
} />
);
}
Dalam contoh ini:
- Rute
<Route path="*" element={<NotFound />} />
adalah rute catch-all yang cocok dengan URL apa pun yang tidak cocok dengan rute lain yang telah ditentukan. - Penting untuk menempatkan rute ini di akhir komponen
<Routes>
sehingga hanya cocok jika tidak ada rute lain yang cocok.
6. Strategi Pemuatan Data dengan React Router v6
React Router v6 tidak menyertakan mekanisme pemuatan data bawaan seperti pendahulunya (React Router v5 dengan `useRouteMatch`). Namun, ia menyediakan alat untuk mengimplementasikan berbagai strategi pemuatan data secara efektif.
Opsi 1: Mengambil Data di Komponen
Pendekatan paling sederhana adalah mengambil data langsung di dalam komponen yang merender rute. Anda dapat menggunakan hook useEffect
untuk mengambil data saat komponen dimuat atau saat parameter URL berubah.
import { useParams } from "react-router-dom";
import { useEffect, useState } from "react";
function ProductDetails() {
const { productId } = useParams();
const [product, setProduct] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
async function fetchProduct() {
try {
const response = await fetch(`/api/products/${productId}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
setProduct(data);
setLoading(false);
} catch (e) {
setError(e);
setLoading(false);
}
}
fetchProduct();
}, [productId]);
if (loading) return Memuat...
;
if (error) return Error: {error.message}
;
if (!product) return Produk tidak ditemukan
;
return (
{product.name}
{product.description}
);
}
export default ProductDetails;
Pendekatan ini mudah tetapi dapat menyebabkan duplikasi kode jika Anda perlu mengambil data di beberapa komponen. Ini juga kurang efisien karena pengambilan data baru dimulai setelah komponen dipasang.
Opsi 2: Menggunakan Hook Kustom untuk Pengambilan Data
Untuk mengurangi duplikasi kode, Anda dapat membuat hook kustom yang mengenkapsulasi logika pengambilan data. Hook ini kemudian dapat digunakan kembali di beberapa komponen.
import { useState, useEffect } from "react";
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
async function fetchData() {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const json = await response.json();
setData(json);
setLoading(false);
} catch (e) {
setError(e);
setLoading(false);
}
}
fetchData();
}, [url]);
return { data, loading, error };
}
export default useFetch;
Kemudian, Anda dapat menggunakan hook ini di komponen Anda:
import { useParams } from "react-router-dom";
import useFetch from "./useFetch";
function ProductDetails() {
const { productId } = useParams();
const { data: product, loading, error } = useFetch(`/api/products/${productId}`);
if (loading) return Memuat...
;
if (error) return Error: {error.message}
;
if (!product) return Produk tidak ditemukan
;
return (
{product.name}
{product.description}
);
}
export default ProductDetails;
Opsi 3: Menggunakan Pustaka Routing dengan Kemampuan Pengambilan Data (TanStack Router, Remix)
Pustaka seperti TanStack Router dan Remix menawarkan mekanisme pengambilan data bawaan yang terintegrasi secara mulus dengan routing. Pustaka-pustaka ini seringkali menyediakan fitur-fitur seperti:
- Loaders: Fungsi yang dieksekusi *sebelum* rute dirender, memungkinkan Anda mengambil data dan meneruskannya ke komponen.
- Actions: Fungsi yang menangani pengiriman formulir dan mutasi data.
Menggunakan pustaka semacam itu dapat secara drastis menyederhanakan pemuatan data dan meningkatkan kinerja, terutama untuk aplikasi yang kompleks.
Server Side Rendering (SSR) dan Static Site Generation (SSG)
Untuk meningkatkan SEO dan performa pemuatan awal, pertimbangkan untuk menggunakan SSR atau SSG dengan kerangka kerja seperti Next.js atau Gatsby. Kerangka kerja ini memungkinkan Anda mengambil data di server atau selama waktu build dan menyajikan HTML pra-render ke klien. Ini menghilangkan kebutuhan klien untuk mengambil data pada pemuatan awal, menghasilkan pengalaman yang lebih cepat dan lebih ramah SEO.
7. Bekerja dengan Jenis Router yang Berbeda
React Router v6 menyediakan implementasi router yang berbeda untuk menyesuaikan dengan berbagai lingkungan dan kasus penggunaan:
- BrowserRouter: Menggunakan API riwayat HTML5 (
pushState
,replaceState
) untuk navigasi. Ini adalah pilihan paling umum untuk aplikasi web yang berjalan di lingkungan browser. - HashRouter: Menggunakan bagian hash dari URL (
#
) untuk navigasi. Ini berguna untuk aplikasi yang perlu mendukung browser lama atau yang di-deploy di server yang tidak mendukung API riwayat HTML5. - MemoryRouter: Menyimpan riwayat "URL" Anda di memori (array URL). Berguna di lingkungan seperti React Native dan pengujian.
Pilih jenis router yang paling sesuai dengan persyaratan dan lingkungan aplikasi Anda.
Kesimpulan
React Router v6 menyediakan solusi routing yang komprehensif dan fleksibel untuk aplikasi React. Dengan memahami dan menerapkan pola navigasi yang dibahas dalam postingan blog ini, Anda dapat membangun aplikasi web yang tangguh, ramah pengguna, dan mudah dikelola. Dari routing deklaratif dengan <Routes>
dan <Route>
hingga rute dinamis dengan parameter URL, navigasi terprogram dengan useNavigate
, dan strategi pemuatan data yang efektif, React Router v6 memberdayakan Anda untuk menciptakan pengalaman navigasi yang mulus bagi pengguna Anda. Pertimbangkan untuk menjelajahi pustaka routing canggih dan kerangka kerja SSR/SSG untuk kontrol dan optimalisasi kinerja yang lebih besar lagi. Ingatlah untuk menyesuaikan pola-pola ini dengan persyaratan aplikasi spesifik Anda dan selalu prioritaskan pengalaman pengguna yang jelas dan intuitif.