When building a React application with nested content, like a movie library where clicking a movie title should show its details within the same page, we need a way to manage these nested views. Think of it like opening a book (the main movies page) and then flipping to a specific chapter (the movie details) - both the book and chapter are visible at the same time. We need to:
Let's look at our file structure first:
src/
├── App.jsx
├── data/
│ └── movieData.js
└── components/
└── Movies/
├── Movies.jsx
├── MovieNavBar.jsx
└── MovieDetails.jsx
// App.jsx
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import Movies from './components/Movies';
import MovieDetails from './components/Movies/MovieDetails';
import { movies } from './data/movieData';
// Create our router with nested routes
const router = createBrowserRouter([
{
path: '/movies',
// Pass movies data as a prop to the Movies component
element: <Movies movies={movies} />,
// Define the nested route for movie details
children: [
{
// :movieId is a dynamic parameter that will change based on selected movie
path: ':movieId',
element: <MovieDetails movies={movies} />
}
]
}
// ... other routes
]);
// Movies/Movies.jsx
import { Outlet } from 'react-router-dom';
import MovieNavBar from './MovieNavBar';
function Movies({ movies }) {
return (
<div>
<h1>Movies Component</h1>
{/* MovieNavBar shows the list of clickable movie titles */}
<MovieNavBar movies={movies} />
{/* Outlet is where the MovieDetails component will render */}
<Outlet />
</div>
);
}
// Movies/MovieNavBar.jsx
import { NavLink } from 'react-router-dom';
function MovieNavBar({ movies }) {
return (
<nav>
{movies.map(movie => (
<NavLink
key={movie.id}
to={`${movie.id}`} // Creates relative path like /movies/1
className={({ isActive }) =>
isActive ? 'active-movie' : ''
}
>
{movie.title}
</NavLink>
))}
</nav>
);
}
// Movies/MovieDetails.jsx
import { useParams } from 'react-router-dom';
function MovieDetails({ movies }) {
// Get the movieId from the URL parameter
const { movieId } = useParams();
// Find the selected movie from our movies array
const movieChoice = movies.find(
movie => movie.id === parseInt(movieId)
);
// If no movie is found, show an error message
if (!movieChoice) {
return <h2>Movie not found!</h2>;
}
return (
<div>
<h1>{movieChoice.title}</h1>
<p>{movieChoice.description}</p>
</div>
);
}
Think of nested routes like a library organization system:
Here are some typical issues new developers face when working with nested routes:
If you're not seeing the nested content, check that:
Remember that URL parameters are always strings. When comparing with numeric IDs:
To verify your nested routing is working correctly:
This nested routing pattern is commonly used in:
To better understand nested routes, try these challenges:
When troubleshooting nested routes, remember to: