ReactFlix uses React Router DOM v7 for client-side routing, enabling seamless navigation without page reloads. This guide covers the routing architecture, configuration, and navigation patterns.
Router Configuration
The routing system is configured in src/App.js:1 using React Router DOM’s declarative API.
Route Setup
import { BrowserRouter as Router , Routes , Route } from 'react-router-dom' ;
import Header from './components/Header' ;
import Footer from './components/Footer' ;
import PrincipalPage from './pages/PrincipalPage' ;
import PeliculasPage from './pages/PeliculasPage' ;
import PeliculaDetailPage from './pages/PeliculaDetailPage' ;
import AlquileresPage from './pages/AlquileresPage' ;
import ComprasPage from './pages/ComprasPage' ;
function App () {
return (
< Router >
< div className = "app" >
< Header />
< main className = "app__main" >
< Routes >
< Route path = "/" element = { < PrincipalPage /> } />
< Route path = "/peliculas" element = { < PeliculasPage /> } />
< Route path = "/pelicula/:id" element = { < PeliculaDetailPage /> } />
< Route path = "/gestion-alquileres" element = { < AlquileresPage /> } />
< Route path = "/gestion-compras" element = { < ComprasPage /> } />
</ Routes >
</ main >
< Footer />
</ div >
</ Router >
);
}
The Header and Footer components are rendered outside the Routes component, making them persistent across all pages.
Route Structure
ReactFlix implements 5 main routes:
Path : /Component : PrincipalPagePurpose : Landing page with hero section and featured moviesNavigation : Accessible via site logo and “Inicio” link< Route path = "/" element = { < PrincipalPage /> } />
/peliculas - Catalog Route
Path : /peliculasComponent : PeliculasPagePurpose : Full movie catalog with search and filteringFeatures :
Search by title, director, or cast
Filter by genre
Grid display of all movies
< Route path = "/peliculas" element = { < PeliculasPage /> } />
/pelicula/:id - Detail Route
Path : /pelicula/:idComponent : PeliculaDetailPagePurpose : Detailed view of a single movieURL Parameters :Example URLs :
/pelicula/1 - Inception
/pelicula/4 - The Dark Knight
Features :
Full movie information
Trailer viewing
Rent/purchase actions
< Route path = "/pelicula/:id" element = { < PeliculaDetailPage /> } />
/gestion-alquileres - Rentals Route
Path : /gestion-alquileresComponent : AlquileresPagePurpose : Manage user’s rented moviesFeatures :
View all rented movies
Extend rental periods
Displays rental date
< Route path = "/gestion-alquileres" element = { < AlquileresPage /> } />
/gestion-compras - Purchases Route
Path : /gestion-comprasComponent : ComprasPagePurpose : Library of purchased moviesFeatures :
View all purchased movies
Access anytime (no expiration)
Purchase history
< Route path = "/gestion-compras" element = { < ComprasPage /> } />
Navigation Implementation
The Header component (src/components/Header.jsx:1) implements navigation with active state highlighting:
import { Link , useLocation } from "react-router-dom" ;
const Header = () => {
const location = useLocation ();
return (
< header className = "header" >
< div className = "header__container" >
< Link to = "/" className = "header__logo" >
< h1 > React < span > Flix </ span ></ h1 >
</ Link >
< nav className = "header__nav" >
< ul className = "header__nav-list" >
< li className = "header__nav-item" >
< Link
to = "/"
className = { `header__nav-link ${
location . pathname === "/" ? "header__nav-link--active" : ""
} ` }
>
Inicio
</ Link >
</ li >
< li className = "header__nav-item" >
< Link
to = "/peliculas"
className = { `header__nav-link ${
location . pathname === "/peliculas" ? "header__nav-link--active" : ""
} ` }
>
Películas
</ Link >
</ li >
{ /* More nav items... */ }
</ ul >
</ nav >
</ div >
</ header >
);
};
Import Navigation Hooks
Import Link for navigation and useLocation for active state: import { Link , useLocation } from "react-router-dom" ;
Get Current Location
Use the useLocation hook to access current path: const location = useLocation ();
Conditional Class Names
Apply active class based on current path: className = { `header__nav-link ${
location . pathname === "/peliculas" ? "header__nav-link--active" : ""
} ` }
The Link component prevents full page reloads and provides a better user experience than traditional <a> tags.
Programmatic Navigation
ReactFlix uses the useNavigate hook for programmatic navigation in response to user actions.
Example : Detail page navigation (src/pages/PeliculaDetailPage.jsx:11)
import { useNavigate } from 'react-router-dom' ;
const PeliculaDetailPage = () => {
const navigate = useNavigate ();
if ( ! pelicula ) {
return (
< div className = "pelicula-detail__not-found" >
< h2 > Película no encontrada </ h2 >
< button
onClick = { () => navigate ( '/peliculas' ) }
className = "pelicula-detail__back-btn"
>
Volver al catálogo
</ button >
</ div >
);
}
};
Navigation from Cards (src/components/PeliculaCard.jsx):
import { Link } from 'react-router-dom' ;
< Link
to = { `/pelicula/ ${ pelicula . id } ` }
className = "pelicula-card__details-btn"
>
Ver Detalles
</ Link >
URL Parameters
Accessing Route Parameters
The detail page uses useParams to extract the movie ID from the URL:
import { useParams } from 'react-router-dom' ;
import { mockPeliculas } from '../data/mockPeliculas' ;
const PeliculaDetailPage = () => {
const { id } = useParams ();
const [ pelicula , setPelicula ] = useState ( null );
useEffect (() => {
const timer = setTimeout (() => {
const foundPelicula = mockPeliculas . find (
m => m . id === parseInt ( id )
);
setPelicula ( foundPelicula );
setLoading ( false );
}, 500 );
return () => clearTimeout ( timer );
}, [ id ]);
};
Extract Parameter
const { id } = useParams ();
This extracts the :id parameter from /pelicula/:id
Convert Type
URL parameters are strings, so convert to number for comparison
Find Movie
mockPeliculas . find ( m => m . id === parseInt ( id ))
Search the dataset for matching movie
Handle Not Found
if ( ! pelicula ) {
return < NotFoundComponent /> ;
}
Display error state if movie doesn’t exist
Parameter Re-fetching
The useEffect dependency array includes id, causing data re-fetch when the parameter changes:
useEffect (() => {
// Fetch logic
}, [ id ]); // Re-run when id changes
This allows users to navigate between detail pages without returning to the catalog - the component updates with new data.
Router Features
BrowserRouter
ReactFlix uses BrowserRouter which leverages the HTML5 History API:
Clean URLs URLs look like /peliculas instead of /#/peliculas
Server Config Requires server configuration to serve index.html for all routes
History API Supports browser back/forward buttons
SEO Friendly Better for search engine crawling
Routes vs Switch
React Router v6+ uses <Routes> instead of the older <Switch> component. <Routes> provides better performance and improved route matching.
Navigation Patterns
Link-Based Navigation
Use Case : Static navigation, links in content
import { Link } from 'react-router-dom' ;
< Link to = "/peliculas" > Browse Movies </ Link >
Use Case : Actions after user interactions, callbacks
import { useNavigate } from 'react-router-dom' ;
const MyComponent = () => {
const navigate = useNavigate ();
const handleAction = () => {
// Perform some logic
navigate ( '/success' );
};
return < button onClick = { handleAction } > Submit </ button > ;
};
Conditional Navigation
Use Case : Navigate based on conditions
const handleRent = ( pelicula ) => {
// Save to localStorage
localStorage . setItem ( 'alquileres' , JSON . stringify ([ ... alquileres , pelicula ]));
// Navigate to rentals page
navigate ( '/gestion-alquileres' );
};
Active Link Styling
ReactFlix implements custom active link styling:
CSS (src/styles/components.css:48):
.header__nav-link--active {
color : #e50914 ;
font-weight : bold ;
}
JavaScript Logic :
const isActive = location . pathname === "/peliculas" ;
const className = `header__nav-link ${ isActive ? "header__nav-link--active" : "" } ` ;
Alternative: NavLink Component
React Router provides a NavLink component with built-in active state: import { NavLink } from 'react-router-dom' ;
< NavLink
to = "/peliculas"
className = { ({ isActive }) =>
`header__nav-link ${ isActive ? "header__nav-link--active" : "" } `
}
>
Películas
</ NavLink >
This approach is cleaner but ReactFlix uses manual implementation with useLocation.
Route Protection
ReactFlix currently has no authentication or route protection. All routes are publicly accessible.
To add protected routes:
const ProtectedRoute = ({ children }) => {
const isAuthenticated = // check auth state
if ( ! isAuthenticated ) {
return < Navigate to = "/login" replace /> ;
}
return children ;
};
// Usage
< Route
path = "/gestion-alquileres"
element = {
< ProtectedRoute >
< AlquileresPage />
</ ProtectedRoute >
}
/>
404 Handling
ReactFlix doesn’t currently implement a catch-all 404 route. To add one:
import NotFoundPage from './pages/NotFoundPage' ;
< Routes >
< Route path = "/" element = { < PrincipalPage /> } />
{ /* Other routes */ }
< Route path = "*" element = { < NotFoundPage /> } />
</ Routes >
The * path matches any route not previously defined.
Best Practices
Use Link for Navigation
Always use <Link> instead of <a> tags to prevent full page reloads: ✅ < Link to = "/peliculas" > Movies </ Link >
❌ < a href = "/peliculas" > Movies </ a >
Extract Route Parameters
Always validate and type-convert URL parameters: const { id } = useParams ();
const numericId = parseInt ( id );
if ( isNaN ( numericId )) {
// Handle invalid ID
}
Handle Loading States
Show loading indicators during route transitions with data fetching: if ( loading ) return < LoadingSpinner /> ;
Clean Up Effects
Return cleanup functions in useEffect hooks: useEffect (() => {
const timer = setTimeout ( ... );
return () => clearTimeout ( timer );
}, [ id ]);
Project Structure Understand how routes map to page components
Data Management Learn how pages fetch and manage data