# Chapitre 3 : Composants
## Qu'est-ce qu'un composant ?
Un composant est une fonction JavaScript qui retourne du JSX :
```javascript
function Welcome() {
return
Bonjour !
;
}
```
C'est tout. Une fonction qui retourne de l'UI.
## Conventions de nommage
- **PascalCase** pour les noms de composants : `UserCard`, `LoginForm`, `NavigationMenu`
- Les composants commençant par une minuscule sont traités comme des balises HTML
```javascript
// CORRECT
function UserCard() { ... }
// INCORRECT - traité comme une balise HTML
function userCard() { ... }
// Ne fonctionne pas !
```
## Props : passer des données
Les props (properties) permettent de passer des données à un composant :
```javascript
// Définition du composant avec props
function Welcome({ name }) {
return
Bonjour, {name} !
;
}
// Utilisation
```
### Plusieurs props
```javascript
function UserCard({ name, email, role }) {
return (
{name}
{email}
{role}
);
}
```
### Props avec valeur par défaut
```javascript
function Button({ label, type = "button", disabled = false }) {
return (
);
}
```
### Props de type différent
```javascript
function Product({ name, price, inStock, tags, onClick }) {
return (
{name}
{price} €
{inStock && En stock}
{tags.map(tag =>
{tag}
)}
);
}
console.log('Cliqué')}
/>
```
^ Type ^ Exemple ^
| String | `name="Jean"` |
| Number | `age={30}` |
| Boolean | `active={true}` ou juste `active` |
| Array | `items={[1, 2, 3]}` |
| Object | `user={{ name: 'Jean' }}` |
| Function | `onClick={() => {}}` |
## Props children
La prop spéciale `children` contient le contenu entre les balises ouvrante et fermante :
```javascript
function Card({ title, children }) {
return (
{title}
{children}
);
}
// Utilisation
Ceci est le contenu de la carte.
```
C'est très utile pour créer des composants "wrapper" ou "layout".
## Composition de composants
Les composants peuvent utiliser d'autres composants :
```javascript
function Avatar({ src, alt }) {
return ;
}
function UserInfo({ name, email }) {
return (
{name}{email}
);
}
function UserCard({ user }) {
return (
);
}
function UserList({ users }) {
return (
{users.map(user => (
))}
);
}
```
Hiérarchie : `UserList` → `UserCard` → `Avatar` + `UserInfo`
## Props sont en lecture seule
**Règle fondamentale** : un composant ne doit jamais modifier ses props.
```javascript
// INCORRECT - ne jamais faire ça !
function BadComponent({ user }) {
user.name = "Modifié"; // INTERDIT !
return
{user.name}
;
}
// CORRECT - les props sont immuables
function GoodComponent({ user }) {
return
{user.name}
;
}
```
Si vous devez modifier des données, utilisez l'état (useState - prochain module).
## Déstructuration des props
Plusieurs façons de récupérer les props :
```javascript
// 1. Déstructuration dans les paramètres (recommandé)
function UserCard({ name, email }) {
return
{name} - {email}
;
}
// 2. Déstructuration dans le corps
function UserCard(props) {
const { name, email } = props;
return
{name} - {email}
;
}
// 3. Sans déstructuration
function UserCard(props) {
return
{props.name} - {props.email}
;
}
```
## Spread de props
Pour transférer toutes les props à un élément enfant :
```javascript
function Button({ children, ...rest }) {
return (
);
}
// Utilisation - onClick et disabled sont passés au button
```
## Organisation des fichiers
Convention SmartMaker : un composant par dossier avec `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 (
{user.name}
{user.email}
);
}
// Import
import UserCard from 'src/components/UserCard';
```
## Exercices
### Exercice 1 : Créer un composant Button
Créer un composant `Button` qui accepte :
- `label` : texte du bouton
- `variant` : "primary" ou "secondary" (défaut: "primary")
- `onClick` : fonction à appeler au clic
**Solution :**
```javascript
function Button({ label, variant = "primary", onClick }) {
return (
);
}
// Utilisation