Chapitre 20 — Mini-projet complet (mise en pratique)
À ce stade, vous savez créer des composants, gérer le state, faire des effets, router, etc. La différence entre un projet “qui marche” et un projet “pro” tient souvent à la structure et aux patterns (schémas de conception) utilisés. Dans ce chapitre, on pose des règles simples, très utiles pour progresser rapidement.
Plan du chapitre
- 1) Nommage et lisibilité
- 2) Découper en composants : règle simple
- 3) Composition : “assembler” plutôt que dupliquer
- 4) Lifting state up : remonter le state au bon niveau
- 5) Composants contrôlés vs non contrôlés
- 6) Organisation des dossiers
- 7) Anti-patterns courants (débutants)
- 8) Résumé (à retenir)
- 9) Exercice pratique
1) Nommage et lisibilité
En React, vous lisez du code plus que vous n’en écrivez. Le nommage est donc capital.
- Composants : PascalCase (
UserCard,ProductList) - Fonctions : camelCase (
handleSubmit,toggleTheme) - Handlers : préfixe
handleouon(ex :onDelete) - Booleans : commence souvent par
is,has,can
const [isOpen, setIsOpen] = useState(false);
const [hasError, setHasError] = useState(false);
function handleOpen() { setIsOpen(true); }
2) Découper en composants : règle simple
Si un composant dépasse ~150 lignes et mélange beaucoup de responsabilités, c’est souvent un signe qu’il faut découper.
Règle pratique
- Un composant = une idée principale
- La page assemble des composants
- Le composant enfant se concentre sur un rôle précis (afficher, saisir, etc.)
Exemple : une page “Users” assemble : SearchBar, UserList, UserCard.
3) Composition : “assembler” plutôt que dupliquer
En React, on évite de copier-coller des blocs. On préfère créer des composants réutilisables et les assembler.
Exemple : un composant Card réutilisable
export default function Card({ title, children }) {
return (
<section className="card">
<h3>{title}</h3>
<div>{children}</div>
</section>
);
}
Utilisation
<Card title="Profil">
<p>Nom : Ahmed</p>
</Card>
<Card title="Réglages">
<button>Activer les notifications</button>
</Card>
Le pattern children est l’un des plus importants en React : vous “injectez” du contenu.
4) Lifting state up : remonter le state au bon niveau
Problème classique : deux composants frères doivent partager une information. Exemple : une barre de recherche et une liste filtrée. Si chacun garde son state dans son coin, ils ne peuvent pas se synchroniser.
Solution : on “remonte” le state dans le parent commun, puis on redescend :
- le state en props
- les setters/fonctions en props
UsersPage
├─ SearchBar (met à jour search)
└─ UserList (utilise search)
Exemple minimal
function UsersPage({ users }) {
const [search, setSearch] = useState("");
const filtered = users.filter((u) =>
u.name.toLowerCase().includes(search.toLowerCase())
);
return (
<div>
<SearchBar value={search} onChange={setSearch} />
<UserList users={filtered} />
</div>
);
}
Remonter le state au bon niveau est une compétence essentielle pour structurer une app.
5) Composants contrôlés vs non contrôlés
Vous connaissez déjà les champs contrôlés (value vient du state). Il existe aussi des champs “non contrôlés” via les refs.
A) Contrôlé (recommandé pour débuter)
const [email, setEmail] = useState("");
<input value={email} onChange={(e) => setEmail(e.target.value)} />
B) Non contrôlé (avec useRef)
const inputRef = useRef(null);
const handleSubmit = (e) => {
e.preventDefault();
console.log(inputRef.current.value);
};
<input ref={inputRef} />
Le non contrôlé est utile dans certains cas (performance, intégration libs externes), mais pour apprendre, restez sur le contrôlé.
6) Organisation des dossiers
Une structure simple, claire et adaptée à la majorité des projets :
src/
├─ App.jsx
├─ main.jsx
├─ pages/
├─ components/
├─ layouts/
├─ contexts/
├─ hooks/
├─ services/
└─ assets/
pages/: pages routéescomponents/: UI réutilisableservices/: appels API (fetch), helpershooks/: hooks customcontexts/: Context API
7) Anti-patterns courants (débutants)
Mettre trop de logique dans un seul composant “page”
Découpez : UI (components) + logique (hooks/services) + page (assemblage).
Utiliser le state alors qu’un simple calcul suffit
Si une valeur peut être calculée à partir d’autres states/props, calculez-la dans le rendu
(ou useMemo si nécessaire) au lieu de stocker un “double state”.
Dupliquer le même code (copier-coller)
Transformez en composant (ou en fonction utilitaire) et réutilisez.
Gérer des side effects au mauvais endroit
Les side effects (fetch, timer, subscription) vont dans useEffect,
pas dans le rendu, ni dans un reducer.
8) Résumé (à retenir)
- Découpez : un composant = un rôle principal.
- Préférez la composition à la duplication (
children). - Remontez le state au bon niveau (lifting state up).
- Structurez vos dossiers : pages / components / services / hooks / contexts.
- Ne stockez pas dans le state ce qui peut être calculé.
9) Exercice pratique
Objectif : appliquer la composition et le lifting state up sur un mini-projet.
Consigne
- Créez une page
ProductsPageavec une liste de produits (tableau en dur). - Ajoutez une barre de recherche
SearchBar(input contrôlé). - Filtrez les produits dans la page (state remonte au parent).
- Affichez les produits via
ProductListetProductCard. - Créez un composant
Cardréutilisable avecchildren.
Bonus
Ajoutez un tri (prix croissant/décroissant) en gardant une structure propre (state au bon endroit).
Prochaine étape : Chapitre 21 — Hooks personnalisés : créer vos propres hooks (useLocalStorage, useFetch, etc.).