4.8 Utiliser un état à la place (et ce qui est mieux)
Dans le cours précédent, nous mettions à jour l'état combiné en passant directement un nouvel objet à setUserInput, en référant à userInput via le spread. Ce code fonctionne dans la plupart des cas, mais il cache un piège subtil : React peut planifier plusieurs mises à jour à la chaîne, et la variable userInput à laquelle on se réfère peut ne pas être la valeur la plus récente.
La forme fonction de useState
Pour éviter ce problème, React fournit une forme fonction de la fonction de mise à jour. Au lieu de passer un nouvel objet directement, on lui passe une fonction qui reçoit le dernier instantané d'état en paramètre. Cette fonction est exécutée automatiquement par React avec la version garantie la plus à jour de l'état :
const titleChangeHandler = (event) => {
setUserInput((prevState) => {
return {
...prevState,
enteredTitle: event.target.value
};
});
};
prevState est juste un nom de paramètre — vous pouvez l'appeler comme vous voulez. C'est React qui se charge de lui passer l'instantané précédent, stocké de manière native dans le hook. À l'intérieur de la fonction, on retourne le nouvel objet d'état, construit avec le spread (...prevState) pour préserver les autres propriétés et en remplaçant uniquement la clé concernée (enteredTitle) par la valeur cible de l'événement (event.target.value).
C'est quelque chose qu'il faut garder à l'esprit en général : dès que vous mettez à jour un état qui dépend de l'état précédent (en fusionnant un objet ou en incrémentant un compteur, par exemple), utilisez la forme fonction. C'est plus sûr et évite des bugs subtils en cas de mises à jour rapprochées. Pour la suite du projet, nous allons revenir à l'approche multi-états séparés (un useState par champ), qui reste la plus lisible dans notre cas.
En résumé
Lorsque vous mettez à jour un état React qui dépend de l'état précédent, il est préférable de transmettre une fonction anonyme au lieu d'appeler directement la fonction de mise à jour. Cette fonction reçoit `prevState` comme paramètre et permet d'accéder à l'instantané d'état précédent de manière fiable. En utilisant le spread operator pour fusionner l'état, vous évitez les dépendances non intentionnelles et assurez que votre composant réagit correctement aux changements.
Points clés
- Fonction vs appel direct — Transmettez une fonction fléchée anonyme à setState plutôt que d'appeler directement la fonction de mise à jour
- Accès à prevState — Le paramètre `prevState` de la fonction de rappel contient l'instantané d'état précédent, critique quand vous fusionnez plusieurs propriétés d'état
- Spread operator pour fusionner — Utilisez le spread operator (`...`) pour copier l'état précédent et y ajouter vos modifications, afin de ne pas perdre d'autres propriétés
- Cas d'usage multi-propriétés — Cette approche est essentielle quand votre état contient plusieurs champs (ex. `title`, `description`) et que vous en modifiez un seul
- Réactivité garantie — React exécute automatiquement la fonction avec l'état actuel au moment de la mise à jour, assurant la cohérence
Questions fréquentes
Pourquoi ne pas appeler directement la fonction de mise à jour ?
Parce que vous ne seriez pas sûr de l'état actuel au moment de l'exécution. En transmettant une fonction, React vous garantit que `prevState` contient l'instantané exact de l'état au moment du traitement.
Quand dois-je utiliser le spread operator dans la mise à jour d'état ?
Chaque fois que votre état contient plusieurs propriétés et que vous modifiez une seule d'entre elles. Cela garantit que les autres propriétés ne sont pas perdues (ex. `{ ...prevState, title: newTitle }`)
Cette approche est-elle obligatoire pour toutes les mises à jour d'état ?
Non — si votre mise à jour d'état n'a aucune dépendance vis-à-vis des valeurs précédentes, vous pouvez appeler la fonction directement. Mais si vous fusionnez des propriétés ou dépendez d'une valeur précédente, c'est la bonne pratique.