Stop building monolithic files. Learn how to combine small, reusable components into a clean, scalable UI hierarchy using React composition techniques.
Previously in this course, we covered Passing Data with Props and built Dynamic Movie Cards. By now, you know how to create individual building blocks. But a professional application isn't just a pile of isolated cards; it's a structured tree of nested components.
In this lesson, we’ll move from building single components to mastering component composition. This is the art of combining small, focused components into a larger, logical structure.
If you keep every piece of your UI in one file, you end up with "spaghetti code"—a massive, unreadable component that is impossible to debug. By using nested components, you break the UI into a tree-like hierarchy.
Think of our movie-browser app. Instead of one giant App component, we want a structure that looks like this:
App (The root container)
Header (Navigation and branding)Main (Layout wrapper)
MovieList (Container for all cards)
MovieCard (The individual display)Footer (Copyright and links)This isn't just about tidiness. It’s about separation of concerns. Each parent component manages the "where" and "how" of its children, while the children focus strictly on their own rendering.
Let’s evolve our project by creating a Layout component that encapsulates our header and footer, allowing the App component to focus purely on the content.
First, let's create a Header.jsx component:
JSX// components/Header.jsx export function Header() { return ( <header className="site-header"> <h1>MovieBrowser Pro</h1> </header> ); }
Now, instead of manually adding the header and footer to every page, we use a parent Layout component. This component will accept children—a special prop in React that allows you to pass components inside another component.
JSX// components/Layout.jsx import { Header } from CE9178">'./Header'; export function Layout({ children }) { return ( <div className="app-container"> <Header /> <main className="content"> {children} </main> <footer>© 2023 MovieBrowser Inc.</footer> </div> ); }
Now, inside App.jsx, we can wrap our content with this Layout:
JSX// App.jsx import { Layout } from CE9178">'./components/Layout'; import { MovieCard } from CE9178">'./components/MovieCard'; export default function App() { return ( <Layout> <div className="movie-grid"> <MovieCard title="Inception" /> <MovieCard title="Interstellar" /> </div> </Layout> ); }
Notice how App is now much cleaner. It doesn't need to know how the Header is built; it only knows that the Layout provides the structure. This is the core of React composition patterns.
To practice this, take your current movie-browser project and perform these three steps:
Sidebar component.Layout component to include the Sidebar next to the main tag.MovieList into the main section of the Layout.Verify that your styles still apply correctly. If the sidebar appears on the left and the movies on the right, you've successfully managed your first complex UI tree!
<div>. If a piece of UI is only used once and isn't complex, it might be better off staying inside its parent.children prop: Beginners often try to pass components as custom props (like header={<Header />}). While this works, using the children prop is the standard way to compose layouts in React, as discussed in React composition and the children prop for scalable UI libraries.Composition allows us to build complex interfaces by nesting simple, reusable pieces. By utilizing the children prop and organizing our components into a logical tree, we create a codebase that is easier to navigate, test, and maintain.
Up next: We'll explore Conditional Rendering to hide or show parts of our UI based on user interaction.
Master the art of UI state management by adding a filter toggle to your movie app. Learn to control list rendering using boolean state and checkbox inputs.
Component Composition
Polishing the UI
Finalizing the Movie Browser
Review of Component Lifecycle
Review of State Management
Building a Modal Component
Introduction to PropTypes
Performance Optimization Basics
Handling Browser History
Working with LocalStorage
Building a Favorites List
Handling Media in React
Introduction to Testing
Debugging React Apps
Deployment Basics
Using External Libraries
Advanced