- Tác giả

- Name
- Nguyễn Đức Xinh
- Ngày xuất bản
- Ngày xuất bản
React Router: Hướng Dẫn Hoàn Chỉnh về Routing trong React Apps
Tổng Quan về React Router
React Router là library routing declarative cho React applications. Với hơn 56.1k stars trên GitHub và được sử dụng bởi 11 triệu repositories, React Router là standard để xây dựng single-page applications (SPA) với multiple views.
React Router v7 là phiên bản mới nhất, đóng vai trò như multi-strategy router bridging từ React 18 đến React 19, có thể sử dụng như một React framework hoặc minimal library.
Lợi Ích Chính
- Routing Khai Báo: Định nghĩa các route sử dụng JSX components
- Routing Lồng Nhau: Hỗ trợ cấu trúc bố cục phức tạp
- Chia Tách Code: Tải chậm theo từng route để tối ưu hiệu suất
- Tải Dữ Liệu: Khả năng tích hợp sẵn để lấy dữ liệu
- Quản Lý Lịch Sử: Tích hợp với lịch sử trình duyệt
- Hỗ Trợ TypeScript: Tích hợp TypeScript hoàn chỉnh
Các Chế Độ React Router
React Router v7 cung cấp 3 chế độ chính để sử dụng:
- Chế Độ Khai Báo - Routing khai báo truyền thống
- Chế Độ Dữ Liệu - Routing dựa trên dữ liệu với các bộ tải
- Chế Độ Framework - React framework đầy đủ tính năng
Yêu Cầu Hệ Thống
- React: 18+ (khuyến nghị 18.2+)
- Node.js: 20.19+ hoặc phiên bản mới hơn
- TypeScript: 5.0+ (tùy chọn nhưng được khuyến nghị)
- Trình Quản Lý Package: npm, yarn, pnpm, hoặc bun
Cài Đặt React Router
# Cách 1: Sử dụng react-router trực tiếp (được khuyến nghị)
pnpm install react-router
# Cách 2: Sử dụng react-router-dom (wrapper cho compatibility)
pnpm install react-router-dom@7
# TypeScript types đã được bao gồm trong cả hai packages
Lưu Ý Quan Trọng: react-router-dom vs react-router
Sự Khác Biệt Chính
- react-router: Package chính chứa tất cả logic routing core
- react-router-dom: Trong v7 chỉ là "wrapper" re-export từ react-router
- Khuyến nghị: Sử dụng trực tiếp
react-routercho projects mới
Tại Sao Có Sự Thay Đổi Này?
- Đơn giản hóa: Giảm confusion giữa hai packages
- Tương lai: react-router-dom sẽ được deprecated trong các phiên bản tiếp theo
- Hiệu suất: Ít dependency hơn, bundle size nhỏ hơn
Migration Path
// # Cũ (v6)
import { BrowserRouter } from "react-router-dom"
// # Mới (v7) - Khuyến nghị
import { BrowserRouter } from "react-router"
Thiết Lập Routing Cơ Bản
Chế Độ Khai Báo - Thiết Lập Đơn Giản
Tạo basic routing structure trong src/main.tsx:
// src/main.tsx
import { StrictMode } from "react";
import React from 'react'
import { createRoot } from "react-dom/client";
import { BrowserRouter, Routes, Route } from 'react-router'
import App from './App'
import Home from './pages/Home'
import About from './pages/About'
import NotFound from './pages/NotFound'
import './index.css'
createRoot.createRoot(document.getElementById('root')!).render(
<StrictMode>
<BrowserRouter>
<Routes>
<Route path="/" element={<App />}>
<Route index element={<Home />} />
<Route path="about" element={<About />} />
<Route path="*" element={<NotFound />} />
</Route>
</Routes>
</BrowserRouter>
</StrictMode>,
)
Chế độ Data
Bằng cách tách cấu hình định tuyến ra khỏi quá trình render của React, Data Mode bổ sung thêm chức năng tải dữ liệu, hành động, trạng thái chờ xử lý và nhiều hơn nữa với các API như loader, action và useFetcher.
import {
createBrowserRouter,
RouterProvider,
} from "react-router";
let router = createBrowserRouter([
{
path: "/",
Component: Root,
loader: loadRootData,
},
{
path: "/about",
Component: About,
loader: loadAboutData,
...
}
]);
ReactDOM.createRoot(root).render(
<RouterProvider router={router} />,
);
Component Bố Cục với Outlet
Tạo component bố cục trong src/App.tsx:
// src/App.tsx
import { Outlet, Link, useLocation } from 'react-router'
function App() {
return (
<div className="min-h-screen bg-gray-50">
{/* Navigation Header */}
<nav className="bg-white shadow-md">
<div className="max-w-6xl mx-auto px-4">
<div className="flex justify-between items-center py-4">
<Link to="/" className="text-2xl font-bold text-blue-600">
My App
</Link>
<div className="flex space-x-6">
<NavLink to="/">Home</NavLink>
<NavLink to="/about">About</NavLink>
<NavLink to="/contact">Contact</NavLink>
</div>
</div>
</div>
</nav>
{/* Main Content */}
<main className="max-w-6xl mx-auto px-4 py-8">
<Outlet />
</main>
{/* Footer */}
<footer className="bg-gray-800 text-white text-center py-6">
<p>© 2025 My App. All rights reserved.</p>
</footer>
</div>
)
}
// NavLink với styling
function NavLink({ to, children }: { to: string; children: React.ReactNode }) {
const location = useLocation()
const isActive = location.pathname === to
return (
<Link
to={to}
className={`px-3 py-2 rounded-md transition-colors ${
isActive
? 'bg-blue-600 text-white'
: 'text-gray-700 hover:bg-blue-50 hover:text-blue-600'
}`}
>
{children}
</Link>
)
}
export default App
Các Component Page
Tạo các component cho từng Page:
// src/pages/Home.tsx
export default function Home() {
return (
<div>
<h1 className="text-4xl font-bold text-gray-900 mb-6">
Welcome Home
</h1>
<p className="text-xl text-gray-600 mb-8">
This is the home page of our React Router application.
</p>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<FeatureCard
title="Fast Routing"
description="Lightning-fast client-side routing"
/>
<FeatureCard
title="Code Splitting"
description="Lazy load components for better performance"
/>
<FeatureCard
title="TypeScript"
description="Full TypeScript support out of the box"
/>
</div>
</div>
)
}
function FeatureCard({ title, description }: { title: string; description: string }) {
return (
<div className="bg-white p-6 rounded-lg shadow-md border border-gray-200">
<h3 className="text-xl font-semibold text-gray-900 mb-3">{title}</h3>
<p className="text-gray-600">{description}</p>
</div>
)
}
// src/pages/About.tsx
export default function About() {
return (
<div>
<h1 className="text-4xl font-bold text-gray-900 mb-6">About Us</h1>
<div className="prose max-w-none">
<p className="text-xl text-gray-600 mb-6">
Learn more about our mission and values.
</p>
<p className="text-gray-700 mb-4">
We are dedicated to providing excellent React Router examples
and tutorials for developers around the world.
</p>
</div>
</div>
)
}
// src/pages/NotFound.tsx
import { Link } from 'react-router'
export default function NotFound() {
return (
<div className="text-center">
<h1 className="text-6xl font-bold text-gray-900 mb-4">404</h1>
<h2 className="text-2xl text-gray-600 mb-6">Page Not Found</h2>
<p className="text-gray-500 mb-8">
The page you're looking for doesn't exist.
</p>
<Link
to="/"
className="bg-blue-600 hover:bg-blue-700 text-white px-6 py-3 rounded-lg transition-colors"
>
Go Home
</Link>
</div>
)
}
Khái Niệm Routing Nâng Cao
Route Động với Tham Số
// src/main.tsx - Thêm các route động
<Routes>
<Route path="/" element={<App />}>
<Route index element={<Home />} />
<Route path="users" element={<Users />} />
<Route path="users/:userId" element={<UserProfile />} />
<Route path="users/:userId/posts/:postId" element={<Post />} />
<Route path="*" element={<NotFound />} />
</Route>
</Routes>
// src/pages/UserProfile.tsx
import { useParams, useNavigate } from 'react-router'
export default function UserProfile() {
const { userId } = useParams<{ userId: string }>()
const navigate = useNavigate()
return (
<div className="max-w-2xl mx-auto">
...
<button
onClick={() => navigate('/users')}
className="bg-gray-200 hover:bg-gray-300 text-gray-800 px-4 py-2 rounded-md transition-colors"
>
Quay Lại Danh Sách
</button>
</div>
)
}
Route Được Bảo Vệ với Xác Thực
// src/components/ProtectedRoute.tsx
import { Navigate, useLocation } from 'react-router'
import { useAuth } from '../hooks/useAuth'
interface ProtectedRouteProps {
children: React.ReactNode
}
export default function ProtectedRoute({ children }: ProtectedRouteProps) {
const { isAuthenticated, loading } = useAuth()
const location = useLocation()
if (loading) {
return (
<div className="flex items-center justify-center min-h-screen">
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600"></div>
</div>
)
}
if (!isAuthenticated) {
// Chuyển hướng đến trang đăng nhập với return url
return <Navigate to="/login" state={{ from: location }} replace />
}
return <>{children}</>
}
Kết Luận
React Router mang đến giải pháp Routing mạnh mẽ cho các ứng dụng React với:
✅ Tiếp Cận Đa Chiến Lược: Các chế độ Khai Báo, Dữ Liệu và Framework
✅ Hiệu Suất Cải Tiến: Chia tách code tích hợp sẵn và tối ưu hóa
✅ TypeScript Xuất Sắc: An toàn kiểu dữ liệu hoàn chỉnh với các pattern hiện đại
✅ Tải Dữ Liệu: Các bộ tải và hành động nâng cao
✅ Trải Nghiệm Lập Trình: Công cụ và debug xuất sắc
✅ Sẵn Sàng Cho Tương Lai: Hỗ trợ các tính năng concurrent của React 18+
React Router tiếp tục là chuẩn mực cho client-side routing trong hệ sinh thái React! 🚀
