---
source_hash: "e06b3add"
title: "Chapter 3: Components"
weight: 380
---

# Chapter 3: Components

## What is a Component?

A component is a JavaScript function that returns JSX:

```javascript
function Welcome() {
    return <h1>Hello!</h1>;
}
```

That's it. A function that returns UI.

## Naming Conventions

- **PascalCase** for component names: `UserCard`, `LoginForm`, `NavigationMenu`
- Components starting with lowercase are treated as HTML tags

```javascript
// CORRECT
function UserCard() { ... }
<UserCard />

// INCORRECT - treated as HTML tag <usercard>
function userCard() { ... }
<userCard />  // Doesn't work!
```

## Props: Passing Data

Props (properties) allow you to pass data to a component:

```javascript
// Component definition with props
function Welcome({ name }) {
    return <h1>Hello, {name}!</h1>;
}

// Usage
<Welcome name="Jean" />
<Welcome name="Marie" />
```

### Multiple Props

```javascript
function UserCard({ name, email, role }) {
    return (
        <div className="card">
            <h2>{name}</h2>
            <p>{email}</p>
            <span>{role}</span>
        </div>
    );
}

<UserCard name="Jean" email="jean@example.com" role="Admin" />
```

### Props with Default Values

```javascript
function Button({ label, type = "button", disabled = false }) {
    return (
        <button type={type} disabled={disabled}>
            {label}
        </button>
    );
}

<Button label="Submit" />
<Button label="Submit" type="submit" />
<Button label="Disabled" disabled={true} />
```

### Different Prop Types

```javascript
function Product({ name, price, inStock, tags, onClick }) {
    return (
        <div onClick={onClick}>
            <h3>{name}</h3>
            <p>{price} €</p>
            {inStock && <span>In Stock</span>}
            <ul>
                {tags.map(tag => <li key={tag}>{tag}</li>)}
            </ul>
        </div>
    );
}

<Product
    name="Laptop"
    price={999}
    inStock={true}
    tags={['tech', 'sale']}
    onClick={() => console.log('Clicked')}
/>
```

| Type | Example |
| --- | --- |
| String | `name="Jean"` |
| Number | `age={30}` |
| Boolean | `active={true}` or just `active` |
| Array | `items={[1, 2, 3]}` |
| Object | `user={{ name: 'Jean' }}` |
| Function | `onClick={() => {}}` |

## Children Prop

The special `children` prop contains the content between the opening and closing tags:

```javascript
function Card({ title, children }) {
    return (
        <div className="card">
            <h2>{title}</h2>
            <div className="card-body">
                {children}
            </div>
        </div>
    );
}

// Usage
<Card title="My Title">
    <p>This is the card content.</p>
    <button>Action</button>
</Card>
```

This is very useful for creating "wrapper" or "layout" components.

## Component Composition

Components can use other components:

```javascript
function Avatar({ src, alt }) {
    return <img className="avatar" src={src} alt={alt} />;
}

function UserInfo({ name, email }) {
    return (
        <div className="user-info">
            <span className="name">{name}</span>
            <span className="email">{email}</span>
        </div>
    );
}

function UserCard({ user }) {
    return (
        <div className="user-card">
            <Avatar src={user.avatar} alt={user.name} />
            <UserInfo name={user.name} email={user.email} />
        </div>
    );
}

function UserList({ users }) {
    return (
        <div className="user-list">
            {users.map(user => (
                <UserCard key={user.id} user={user} />
            ))}
        </div>
    );
}
```

Hierarchy: `UserList` -> `UserCard` -> `Avatar` + `UserInfo`

## Props are Read-Only

**Fundamental rule**: a component should never modify its props.

```javascript
// INCORRECT - never do this!
function BadComponent({ user }) {
    user.name = "Modified";  // FORBIDDEN!
    return <div>{user.name}</div>;
}

// CORRECT - props are immutable
function GoodComponent({ user }) {
    return <div>{user.name}</div>;
}
```

If you need to modify data, use state (useState - next module).

## Prop Destructuring

Several ways to extract props:

```javascript
// 1. Destructuring in parameters (recommended)
function UserCard({ name, email }) {
    return <div>{name} - {email}</div>;
}

// 2. Destructuring in body
function UserCard(props) {
    const { name, email } = props;
    return <div>{name} - {email}</div>;
}

// 3. Without destructuring
function UserCard(props) {
    return <div>{props.name} - {props.email}</div>;
}
```

## Prop Spread

To forward all props to a child element:

```javascript
function Button({ children, ...rest }) {
    return (
        <button className="btn" {...rest}>
            {children}
        </button>
    );
}

// Usage - onClick and disabled are passed to button
<Button onClick={handleClick} disabled={isLoading}>
    Submit
</Button>
```

## File Organization

SmartMaker convention: one component per folder with `index.jsx`:

```
src/components/
├── UserCard/
│   └── index.jsx
├── UserList/
│   └── index.jsx
└── common/
    ├── Button/
    │   └── index.jsx
    └── Card/
        └── index.jsx
```

```javascript
// src/components/UserCard/index.jsx
export default function UserCard({ user }) {
    return (
        <div className="user-card">
            <h3>{user.name}</h3>
            <p>{user.email}</p>
        </div>
    );
}

// Import
import UserCard from 'src/components/UserCard';
```

## Exercises

### Exercise 1: Create a Button Component

Create a `Button` component that accepts:

- `label`: button text
- `variant`: "primary" or "secondary" (default: "primary")
- `onClick`: function to call on click

**Solution:**

```javascript
function Button({ label, variant = "primary", onClick }) {
    return (
        <button
            className={`btn btn-${variant}`}
            onClick={onClick}
        >
            {label}
        </button>
    );
}

// Usage
<Button label="Submit" onClick={() => console.log('Submitted')} />
<Button label="Cancel" variant="secondary" onClick={handleCancel} />
```

### Exercise 2: Composition

Create a component structure to display a list of products:

- `ProductList`: receives an array of products
- `ProductCard`: displays a product (name, price)
- `Price`: displays a formatted price with € symbol

**Solution:**

```javascript
function Price({ value }) {
    return <span className="price">{value.toFixed(2)} €</span>;
}

function ProductCard({ product }) {
    return (
        <div className="product-card">
            <h3>{product.name}</h3>
            <Price value={product.price} />
        </div>
    );
}

function ProductList({ products }) {
    return (
        <div className="product-list">
            {products.map(product => (
                <ProductCard key={product.id} product={product} />
            ))}
        </div>
    );
}

// Usage
const products = [
    { id: 1, name: 'Laptop', price: 999.99 },
    { id: 2, name: 'Phone', price: 699.50 }
];

<ProductList products={products} />
```

## Key Points to Remember

1. **Component** = function that returns JSX
2. **PascalCase** for component names
3. **Props**: data passed to the component (read-only)
4. **children**: content between the tags
5. **Composition**: components that use other components
6. **Destructuring**: `function Component({ prop1, prop2 })`

## Module 2 Summary

You now know the basics of React:

| Concept | Description |
| --- | --- |
| JSX | Syntax for writing UI in JavaScript |
| Component | Function that returns JSX |
| Props | Data passed to a component |
| children | Content between tags |
| key | Unique identifier for lists |
| Fragment | `<></>` to return multiple elements |

[<- Previous Chapter](/training/module2-introduction-react/jsx) | [Back to Module](/training/module2-introduction-react) | [Next Module: Fundamentals Hooks ->](/training/module3-hooks-fondamentaux)
