Hooks
Définition
Fonctions React qui permettent d'ajouter de la logique aux composants (état local, effets, contexte). useState, useEffect, useMemo sont les hooks les plus utilisés.
Que sont les hooks
Les hooks sont des fonctions React qui ajoutent état et effets aux composants fonctionnels. Ils ont remplacé les classes en 2019 et constituent désormais la seule façon idiomatique d'écrire des composants React. Les hooks principaux : useState pour un état local, useEffect pour un effet de bord (fetch, abonnement, timer), useMemo pour mémoïser un calcul coûteux, useCallback pour mémoïser une fonction, useContext pour lire un contexte partagé, useReducer pour des états complexes. Tous suivent une convention de nommage qui commence par use, ce qui aide les outils d'analyse à les détecter.
Pourquoi les hooks
Avant les hooks, ces mécanismes nécessitaient des classes React avec des cycles de vie (componentDidMount, componentDidUpdate) verbeux et difficiles à composer. Les hooks ont radicalement simplifié l'écriture des composants : moins de code, moins de boilerplate, des comportements plus faciles à partager. Un composant en hooks tient souvent en 20 lignes là où la version classe en demandait 60. Et surtout, on peut réutiliser une logique d'état entre composants sans hiérarchie de wrappers, ce qui était l'angle mort majeur des classes.
Les hooks principaux
useState retourne une valeur et un setter, et déclenche un re-rendu quand la valeur change. useEffect exécute un effet après le rendu, avec dépendances qui contrôlent le re-déclenchement. useMemo et useCallback mémoïsent valeurs et fonctions pour éviter des recalculs inutiles, à utiliser quand le profilage le justifie, pas par habitude. useContext lit un contexte partagé sans prop drilling. useReducer convient quand l'état devient complexe avec plusieurs actions possibles. useRef stocke une valeur mutable qui ne déclenche pas de rendu. Ce vocabulaire couvre 95% des besoins courants.
Les hooks custom
On peut écrire ses propres hooks (useSomething) pour partager une logique entre plusieurs composants. Exemples typiques : useDebounce pour retarder une valeur, useLocalStorage pour synchroniser un état avec le storage navigateur, useFetch pour gérer un appel API avec loading et error, useMediaQuery pour réagir aux breakpoints CSS. C'est la façon idiomatique de factoriser en React, bien plus propre que les Higher-Order Components ou les Render Props d'autrefois. La règle : si une logique apparaît dans plusieurs composants, on la sort dans un hook custom.
Les règles des hooks
Les hooks suivent deux règles strictes. Première : on les appelle uniquement au niveau supérieur d'un composant ou d'un autre hook, jamais dans une condition, une boucle ou une fonction imbriquée. Deuxième : on les appelle uniquement depuis des composants React ou des hooks custom, jamais depuis du code applicatif quelconque. Le linter eslint-plugin-react-hooks attrape l'essentiel des violations. Ces règles existent parce que React identifie chaque hook par sa position dans l'ordre d'appel. Si l'ordre change entre deux rendus, tout casse.
Les pièges à éviter
Trois pièges classiques. useEffect avec dépendances incorrectes : on oublie une variable dans le tableau de dépendances, ce qui fige l'effet avec une valeur obsolète. Le linter exhaustive-deps signale ce problème, on ne le contourne pas. Boucles infinies : un effect qui modifie un état qu'il observe re-déclenche en boucle. Sur-utilisation de useMemo et useCallback par mimétisme : sans profilage, ces optimisations coûtent plus qu'elles ne rapportent. Et l'état dérivé : si une valeur se calcule depuis une autre, on la calcule pendant le rendu, on ne la stocke pas en state.