Follow AiTechWorlds on LinkedIn for professional AI content!Follow Now →
20 minLesson 20 of 40
React Fundamentals

React Router v6

React Router v6

React Router enables client-side navigation in single-page applications. Instead of the browser requesting a new HTML page, React Router swaps out components based on the URL — making navigation instant.

Setup

npm install react-router-dom
// main.jsx — wrap your app in BrowserRouter
import { BrowserRouter } from "react-router-dom";

ReactDOM.createRoot(document.getElementById("root")).render(
    <BrowserRouter>
        <App />
    </BrowserRouter>
);

Defining Routes

import { Routes, Route } from "react-router-dom";

function App() {
    return (
        <Routes>
            <Route path="/" element={<HomePage />} />
            <Route path="/about" element={<AboutPage />} />
            <Route path="/products" element={<ProductsPage />} />
            <Route path="/products/:id" element={<ProductDetailPage />} />
            <Route path="/dashboard" element={<DashboardLayout />}>
                {/* Nested routes */}
                <Route index element={<DashboardHome />} />
                <Route path="settings" element={<Settings />} />
                <Route path="analytics" element={<Analytics />} />
            </Route>
            <Route path="*" element={<NotFoundPage />} />
        </Routes>
    );
}
import { Link, NavLink, useNavigate } from "react-router-dom";

// Link — declarative navigation
<Link to="/about">About</Link>
<Link to="/products/42">View Product</Link>
<Link to={{ pathname: "/search", search: "?q=react" }}>Search React</Link>

// NavLink — adds active class automatically
<NavLink 
    to="/dashboard"
    className={({ isActive }) => isActive ? "nav-link active" : "nav-link"}
>
    Dashboard
</NavLink>

// useNavigate — programmatic navigation
function LoginForm() {
    const navigate = useNavigate();
    
    async function handleSubmit(e) {
        e.preventDefault();
        await login(form);
        navigate("/dashboard");         // redirect
        navigate("/dashboard", { replace: true }); // replace history entry
        navigate(-1);                   // go back
        navigate(1);                    // go forward
    }
}

URL Parameters

import { useParams } from "react-router-dom";

// Route: /products/:id
function ProductDetailPage() {
    const { id } = useParams();
    
    const [product, setProduct] = useState(null);
    
    useEffect(() => {
        fetch(`/api/products/${id}`).then(r => r.json()).then(setProduct);
    }, [id]);
    
    if (!product) return <p>Loading...</p>;
    return <div>{product.name}</div>;
}

Search Params

import { useSearchParams } from "react-router-dom";

// URL: /products?category=electronics&sort=price
function ProductsPage() {
    const [searchParams, setSearchParams] = useSearchParams();
    
    const category = searchParams.get("category") ?? "all";
    const sort = searchParams.get("sort") ?? "name";
    
    function handleCategoryChange(newCategory) {
        setSearchParams(prev => {
            const next = new URLSearchParams(prev);
            next.set("category", newCategory);
            return next;
        });
    }
    
    // ...
}

Nested Routes with Outlet

// Layout component renders child routes
function DashboardLayout() {
    return (
        <div className="dashboard">
            <nav>
                <NavLink to="/dashboard">Home</NavLink>
                <NavLink to="/dashboard/settings">Settings</NavLink>
                <NavLink to="/dashboard/analytics">Analytics</NavLink>
            </nav>
            <main>
                <Outlet />  {/* child route renders here */}
            </main>
        </div>
    );
}

Protected Routes

function RequireAuth({ children }) {
    const { user } = useAuth();
    const location = useLocation();
    
    if (!user) {
        return <Navigate to="/login" state={{ from: location }} replace />;
    }
    
    return children;
}

// Usage
<Route 
    path="/dashboard" 
    element={<RequireAuth><DashboardLayout /></RequireAuth>}
>

Next lesson: Tailwind CSS — utility-first styling that makes design fast.

📱

Get this course's notes on Telegram!

Free cheat sheets, summaries & practice exercises

Get Notes Free →
!