4.7 état de mise à jour qui dépend de l'état précédent

Dans le cours précédent, nous utilisions trois useState séparés pour le titre, le montant et la date. Cette approche fonctionne, mais on peut aussi regrouper tous les états dans un seul useState qui stocke un objet. C'est ce que nous allons faire dans ce cours, en découvrant au passage le piège classique de la mise à jour d'un état qui dépend de l'état précédent.

Un seul useState avec un objet

On remplace les trois appels par un seul, en passant un objet en valeur initiale (pas une chaîne ni un nombre, vraiment un objet). Chaque propriété représente un champ du formulaire :

const [userInput, setUserInput] = useState({
  enteredTitle: '',
  enteredAmount: '',
  enteredDate: ''
});

Dans titleChangeHandler, on appelle maintenant setUserInput en passant un nouvel objet. Mais attention : si on écrit juste { enteredTitle: event.target.value }, on perd les deux autres propriétés ! C'est ici qu'intervient la partie délicate.

Préserver les autres champs avec le spread operator

Pour conserver les autres valeurs, on utilise les trois petits points ... (le spread operator). Cette syntaxe extrait toutes les paires clé-valeur de l'objet existant, puis on écrase uniquement celle qu'on veut modifier :

const titleChangeHandler = (event) => {
  setUserInput({
    ...userInput,
    enteredTitle: event.target.value
  });
};

Ainsi, les deux autres propriétés (enteredAmount et enteredDate) sont copiées intactes, et seul enteredTitle reçoit la nouvelle valeur. On applique exactement la même logique pour amountChangeHandler et dateChangeHandler, en remplaçant la clé appropriée à chaque fois.

Vous pouvez choisir l'approche qui vous convient le mieux : trois useState séparés (plus simple) ou un seul useState avec objet (plus regroupé). Mais ce code n'est pas encore parfait : il y a un piège subtil quand on dépend de l'état précédent. On va voir ça dans le prochain cours.

En résumé

Découvrez comment gérer un état objet en React en mettant à jour sélectivement une propriété sans perdre les autres. Cette leçon enseigne l'utilisation du spread operator pour fusionner les anciennes et nouvelles valeurs, garantissant que toutes les données de l'état restent intactes lors de chaque modification.

Points clés

  • Utiliser un objet comme valeur d'état React avec plusieurs propriétés imbriquées
  • Appliquer le spread operator (...) pour extraire et préserver l'ensemble des propriétés existantes avant la mise à jour
  • Écraser sélectivement une seule propriété tout en conservant les autres données de l'état intactes
  • Assurer la non-perte de données lors de mises à jour partielles en mélangeant l'état précédent avec les nouvelles valeurs
  • Répliquer ce pattern sur plusieurs états indépendants dans le même composant

Questions fréquentes

Comment éviter de perdre les autres propriétés de mon état objet lors d'une mise à jour ?

Utilisez le spread operator (...) pour copier toutes les propriétés existantes, puis spécifiez la propriété à mettre à jour après le spread. Par exemple: setState({...state, title: newTitle}) préserve toutes les autres propriétés (input, date, etc.) tout en remplaçant uniquement title.

Pourquoi ne pas simplement réassigner une seule propriété de l'état ?

React nécessite une immutabilité stricte pour détecter les changements. Si vous modifiez directement une propriété (state.title = 'new'), React ne détecte pas la modification car l'objet référence reste le même. Le spread operator crée un nouvel objet, ce qui déclenche correctement la détection de changement et la mise à jour du rendu.

Comment appliquer ce pattern quand j'ai plusieurs états objets dans mon composant ?

Appliquez la même technique spread operator à chaque setState: pour mettre à jour un formulaire, utilisez setState({...formState, fieldName: value}); pour un métadonnées, utilisez setMetadata({...metadata, date: newDate}). Chaque état objet suit le même pattern de préservation des propriétés existantes.