How do you implement routing in React applications? Compare different routing solutions.
3 minintermediatereactroutingapplicationssolutions
Quick Answer
Routing in React applications is typically handled by client-side routing libraries since React is a single-page application framework.
Detailed Answer
How do you implement routing in React applications? Compare different routing solutions.
Answer:
Routing in React applications is typically handled by client-side routing libraries since React is a single-page application framework.
React Router (Most Popular):
import { BrowserRouter, Routes, Route, Link, useParams, useNavigate } from 'react-router-dom';
// Basic routing setup
function App() {
return (
<BrowserRouter>
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
<Link to="/users">Users</Link>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/users" element={<Users />} />
<Route path="/users/:id" element={<UserDetail />} />
<Route path="*" element={<NotFound />} />
</Routes>
</BrowserRouter>
);
}
// Using route parameters
function UserDetail() {
const { id } = useParams<{ id: string }>();
const navigate = useNavigate();
return (
<div>
<h2>User {id}</h2>
<button onClick={() => navigate('/users')}>
Back to Users
</button>
</div>
);
}
// Protected routes
function ProtectedRoute({ children }: { children: React.ReactNode }) {
const { user } = useAuth();
if (!user) {
return <Navigate to="/login" replace />;
}
return <>{children}</>;
}
// Usage
<Route
path="/dashboard"
element={
<ProtectedRoute>
<Dashboard />
</ProtectedRoute>
}
/>
Nested Routes:
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Home />} />
<Route path="products" element={<Products />}>
<Route index element={<ProductList />} />
<Route path=":id" element={<ProductDetail />} />
<Route path="new" element={<NewProduct />} />
</Route>
<Route path="about" element={<About />} />
</Route>
</Routes>
</BrowserRouter>
);
}
function Layout() {
return (
<div>
<Header />
<main>
<Outlet /> {/* Renders child routes */}
</main>
<Footer />
</div>
);
}
Route Guards and Authentication:
// Custom hook for authentication
function useAuth() {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
checkAuth().then(user => {
setUser(user);
setLoading(false);
});
}, []);
return { user, loading };
}
// Protected route component
function ProtectedRoute({ children, requiredRole }: {
children: React.ReactNode;
requiredRole?: string;
}) {
const { user, loading } = useAuth();
const location = useLocation();
if (loading) {
return <div>Loading...</div>;
}
if (!user) {
return <Navigate to="/login" state={{ from: location }} replace />;
}
if (requiredRole && user.role !== requiredRole) {
return <Navigate to="/unauthorized" replace />;
}
return <>{children}</>;
}
// Usage
<Route
path="/admin"
element={
<ProtectedRoute requiredRole="admin">
<AdminPanel />
</ProtectedRoute>
}
/>
Alternative Routing Solutions:
1. Next.js Router (File-based routing):
// pages/index.tsx
import { useRouter } from 'next/router';
export default function Home() {
const router = useRouter();
const handleNavigate = () => {
router.push('/about');
};
return (
<div>
<h1>Home Page</h1>
<button onClick={handleNavigate}>Go to About</button>
</div>
);
}
// pages/users/[id].tsx - Dynamic route
export default function UserDetail() {
const router = useRouter();
const { id } = router.query;
return <div>User ID: {id}</div>;
}
2. Wouter (Lightweight alternative):
import { Router, Route, Link, useLocation } from 'wouter';
function App() {
return (
<Router>
<nav>
<Link href="/">Home</Link>
<Link href="/about">About</Link>
</nav>
<Route path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/users/:id" component={UserDetail} />
</Router>
);
}
3. Reach Router (Deprecated, but concepts still relevant):
// Focus management and accessibility features
import { Router, Link, navigate } from '@reach/router';
function App() {
return (
<Router>
<Home path="/" />
<About path="/about" />
<Users path="/users" />
<UserDetail path="/users/:id" />
</Router>
);
}
Routing Best Practices:
- Use BrowserRouter for production - Provides clean URLs
- Implement route guards - Protect sensitive routes
- Handle loading states - Show loading indicators during navigation
- Use lazy loading - Code split routes for better performance
- Handle 404s - Provide fallback routes
- Consider SEO - Use proper meta tags and structured data
// Lazy loading routes
const Home = lazy(() => import('./pages/Home'));
const About = lazy(() => import('./pages/About'));
function App() {
return (
<BrowserRouter>
<Suspense fallback={<div>Loading...</div>}>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</Suspense>
</BrowserRouter>
);
}