Un composant est une fonction JavaScript qui retourne du JSX :
function Welcome() { return <h1>Bonjour !</h1>; }
C'est tout. Une fonction qui retourne de l'UI.
UserCard, LoginForm, NavigationMenu// CORRECT function UserCard() { ... } <UserCard /> // INCORRECT - traité comme une balise HTML <usercard> function userCard() { ... } <userCard /> // Ne fonctionne pas !
Les props (properties) permettent de passer des données à un composant :
// Définition du composant avec props function Welcome({ name }) { return <h1>Bonjour, {name} !</h1>; } // Utilisation <Welcome name="Jean" /> <Welcome name="Marie" />
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" />
function Button({ label, type = "button", disabled = false }) { return ( <button type={type} disabled={disabled}> {label} </button> ); } <Button label="Envoyer" /> <Button label="Soumettre" type="submit" /> <Button label="Désactivé" disabled={true} />
function Product({ name, price, inStock, tags, onClick }) { return ( <div onClick={onClick}> <h3>{name}</h3> <p>{price} €</p> {inStock && <span>En stock</span>} <ul> {tags.map(tag => <li key={tag}>{tag}</li>)} </ul> </div> ); } <Product name="Laptop" price={999} inStock={true} tags={['tech', 'promo']} onClick={() => 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={() => {}} |
La prop spéciale children contient le contenu entre les balises ouvrante et fermante :
function Card({ title, children }) { return ( <div className="card"> <h2>{title}</h2> <div className="card-body"> {children} </div> </div> ); } // Utilisation <Card title="Mon titre"> <p>Ceci est le contenu de la carte.</p> <button>Action</button> </Card>
C'est très utile pour créer des composants “wrapper” ou “layout”.
Les composants peuvent utiliser d'autres composants :
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> ); }
Hiérarchie : UserList → UserCard → Avatar + UserInfo
Règle fondamentale : un composant ne doit jamais modifier ses props.
// INCORRECT - ne jamais faire ça ! function BadComponent({ user }) { user.name = "Modifié"; // INTERDIT ! return <div>{user.name}</div>; } // CORRECT - les props sont immuables function GoodComponent({ user }) { return <div>{user.name}</div>; }
Si vous devez modifier des données, utilisez l'état (useState - prochain module).
Plusieurs façons de récupérer les props :
// 1. Déstructuration dans les paramètres (recommandé) function UserCard({ name, email }) { return <div>{name} - {email}</div>; } // 2. Déstructuration dans le corps function UserCard(props) { const { name, email } = props; return <div>{name} - {email}</div>; } // 3. Sans déstructuration function UserCard(props) { return <div>{props.name} - {props.email}</div>; }
Pour transférer toutes les props à un élément enfant :
function Button({ children, ...rest }) { return ( <button className="btn" {...rest}> {children} </button> ); } // Utilisation - onClick et disabled sont passés au button <Button onClick={handleClick} disabled={isLoading}> Envoyer </Button>
Convention SmartMaker : un composant par dossier avec index.jsx :
src/components/
├── UserCard/
│ └── index.jsx
├── UserList/
│ └── index.jsx
└── common/
├── Button/
│ └── index.jsx
└── Card/
└── index.jsx
// 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';
Créer un composant Button qui accepte :
label : texte du boutonvariant : “primary” ou “secondary” (défaut: “primary”)onClick : fonction à appeler au clicSolution :
function Button({ label, variant = "primary", onClick }) { return ( <button className={`btn btn-${variant}`} onClick={onClick} > {label} </button> ); } // Utilisation <Button label="Envoyer" onClick={() => console.log('Envoyé')} /> <Button label="Annuler" variant="secondary" onClick={handleCancel} />
Créer une structure de composants pour afficher une liste de produits :
ProductList : reçoit un tableau de produitsProductCard : affiche un produit (nom, prix)Price : affiche un prix formaté avec le symbole €Solution :
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> ); } // Utilisation const products = [ { id: 1, name: 'Laptop', price: 999.99 }, { id: 2, name: 'Phone', price: 699.50 } ]; <ProductList products={products} />
function Component({ prop1, prop2 })Vous connaissez maintenant les bases de React :
| Concept | Description |
|---|---|
| JSX | Syntaxe pour écrire de l'UI en JavaScript |
| Composant | Fonction qui retourne du JSX |
| Props | Données passées à un composant |
| children | Contenu entre les balises |
| key | Identifiant unique pour les listes |
| Fragment | <></> pour retourner plusieurs éléments |
← Chapitre précédent | Retour au module | Module suivant : Hooks Fondamentaux →