🔥 0
0
Lesson 3 of 9 20 min +100 XP

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 children for 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.

🧠 Quick Quiz

Test your understanding of this lesson.

1

What are props in React?

2

Can a component modify its own props?

3

What does the 'children' prop contain?

JSX Basics