Building Components
Components are the building blocks of React applications. They let you split the UI into independent, reusable pieces that can be thought of in isolation.
What is a Component?
A component is a JavaScript function that returns JSX. Think of it as a custom HTML element that encapsulates its own logic and styling.
// A simple component
function Welcome() {
return <h1>Hello, Developer!</h1>;
}
// Using the component
function App() {
return (
<div>
<Welcome />
<Welcome />
<Welcome />
</div>
);
}
Props: Passing Data to Components
Props (short for "properties") let you pass data from a parent component to a child component. They make components reusable with different data.function UserCard({ name, role, avatar }) {
return (
<div className="card">
<img src={avatar} alt={name} />
<h2>{name}</h2>
<p>{role}</p>
</div>
);
}
// Using with different data
function Team() {
return (
<div>
<UserCard
name="Alice"
role="Developer"
avatar="/alice.jpg"
/>
<UserCard
name="Bob"
role="Designer"
avatar="/bob.jpg"
/>
</div>
);
}
Props are Read-Only
A component must never modify its own props. They are immutable:
// ❌ Wrong - never mutate props
function Broken({ count }) {
count = count + 1; // Don't do this!
return <span>{count}</span>;
}
// ✅ Correct - use state for mutable data
function Counter({ initialCount }) {
const [count, setCount] = useState(initialCount);
return (
<button onClick={() => setCount(count + 1)}>
{count}
</button>
);
}
Default Props
Provide default values for optional props:
function Button({ label = "Click Me", variant = "primary" }) {
return (
<button className={`btn btn-${variant}`}>
{label}
</button>
);
}
// All of these work
<Button />
<Button label="Submit" />
<Button label="Cancel" variant="secondary" />
The children Prop
The special children prop contains whatever is placed between component tags:
function Card({ title, children }) {
return (
<div className="card">
<h2>{title}</h2>
<div className="card-body">
{children}
</div>
</div>
);
}
// Usage
<Card title="Welcome">
<p>This content appears inside the card!</p>
<button>Learn More</button>
</Card>
Component Composition
Build complex UIs by composing smaller components:
function Avatar({ src, alt }) {
return <img className="avatar" src={src} alt={alt} />;
}
function UserInfo({ name, bio }) {
return (
<div className="user-info">
<h3>{name}</h3>
<p>{bio}</p>
</div>
);
}
function UserProfile({ user }) {
return (
<div className="profile">
<Avatar src={user.avatar} alt={user.name} />
<UserInfo name={user.name} bio={user.bio} />
</div>
);
}
Component Best Practices
1. Single Responsibility
Each component should do one thing well:
// ❌ Too much responsibility
function UserDashboard() {
// Fetches data, renders sidebar, shows notifications,
// displays user profile, handles settings...
}
// ✅ Split into focused components
function UserDashboard() {
return (
<div>
<Sidebar />
<MainContent>
<UserProfile />
<Notifications />
</MainContent>
</div>
);
}
2. Keep Components Small
If a component is getting too large (100+ lines), consider splitting it:
// Before: One big component
function ProductPage() {
return (
<div>
{/* 50 lines of header code */}
{/* 100 lines of product details */}
{/* 75 lines of reviews */}
</div>
);
}
// After: Composed of smaller components
function ProductPage() {
return (
<div>
<ProductHeader />
<ProductDetails />
<ProductReviews />
</div>
);
}
3. Descriptive Names
Use clear, descriptive names that explain what the component does:
// ❌ Vague names
<Card />
<Item />
<Box />
// ✅ Descriptive names
<ProductCard />
<CartItem />
<SearchResultsBox />
Putting It Together: A Complete Example
function App() {
const products = [
{ id: 1, name: "Laptop", price: 999, inStock: true },
{ id: 2, name: "Phone", price: 699, inStock: true },
{ id: 3, name: "Tablet", price: 499, inStock: false },
];
return (
<div className="app">
<Header title="Tech Store" />
<ProductGrid products={products} />
<Footer />
</div>
);
}
function ProductGrid({ products }) {
return (
<div className="grid">
{products.map(product => (
<ProductCard key={product.id} product={product} />
))}
</div>
);
}
function ProductCard({ product }) {
const { name, price, inStock } = product;
return (
<div className="card">
<h3>{name}</h3>
<p className="price">${price}</p>
<Badge available={inStock} />
<button disabled={!inStock}>
{inStock ? 'Add to Cart' : 'Out of Stock'}
</button>
</div>
);
}
function Badge({ available }) {
return (
<span className={available ? 'badge-green' : 'badge-red'}>
{available ? 'In Stock' : 'Sold Out'}
</span>
);
}
Key Takeaways
- Components are functions that return JSX
- Props pass data from parent to child components
- Props are read-only - never mutate them
- Use
childrenfor flexible component composition - Keep components small and focused on a single responsibility
- Use descriptive names that explain the component's purpose
Congratulations! You've completed the React Fundamentals course. You now understand the core concepts needed to build React applications.