Relier un champ à son état
Objectif : Synchroniser le champ montant du formulaire avec une valeur d’état React.
Un champ de formulaire peut afficher une valeur sans que React la mémorise. Dans ce cas, votre interface et les données utilisées par le composant ne sont pas synchronisées. Vous allez relier le champ montant de FormulaireDepense à l’état déjà créé, afin que chaque saisie mette à jour la valeur détenue par React.
Dans la leçon précédente, vous avez créé cet état avec useState. Vous allez maintenant l’utiliser dans le JSX du champ et lui transmettre une fonction appelée à chaque changement. Le champ devient ainsi contrôlé : sa valeur affichée provient de l’état, et non d’une valeur indépendante conservée par le navigateur.
Relier le champ à l’état
Dans src/composants/FormulaireDepense.tsx, associez la valeur de l’état à la propriété JSX value. Ajoutez aussi onChange : React appelle ce gestionnaire lorsque la valeur du champ change. L’événement fournit la valeur saisie sous forme de texte ; convertissez-la en nombre avant de la mémoriser dans l’état numérique.
import { useState } from "react";
import type { ChangeEvent } from "react";
export default function FormulaireDepense() {
const [montant, setMontant] = useState<number>(0);
function gererChangementMontant(
evenement: ChangeEvent<HTMLInputElement>,
) {
setMontant(Number(evenement.currentTarget.value));
}
return (
<section className="depenses-saisie" aria-label="Saisir une dépense">
<h2>Ajouter une dépense</h2>
<form>
<label>
Description
<input
className="depenses-saisie__champ"
type="text"
name="description"
/>
</label>
<label>
Montant
<input
className="depenses-saisie__champ"
type="number"
name="montant"
value={montant}
onChange={gererChangementMontant}
/>
</label>
<label>
Catégorie
<select className="depenses-saisie__champ" name="categorie">
<option value="">Choisir une catégorie</option>
</select>
</label>
<label>
Date
<input
className="depenses-saisie__champ"
type="date"
name="date"
/>
</label>
<button className="depenses-saisie__bouton" type="submit">
Ajouter
</button>
</form>
</section>
);
}Le type ChangeEvent<HTMLInputElement> décrit ici l’événement émis par le champ de saisie. currentTarget.value contient le texte actuellement présent dans ce champ ; Number(...) le convertit en nombre pour respecter le type number de l’état. La fonction setMontant déclenche ensuite un nouveau rendu avec la valeur actualisée.
Vérifier la synchronisation
Lancez l’application et saisissez une valeur dans le champ Montant. À chaque frappe, le gestionnaire lit le contenu du champ, le convertit, puis met à jour l’état ; le rendu suivant affiche cette valeur dans le même champ. Le composant ne conserve donc pas une seconde copie du montant : l’état React est la source de la valeur affichée.
Avec le code fourni, la valeur initiale est 0. Si vous effacez le contenu d’un champ numérique, le navigateur transmet une chaîne vide et Number("") produit 0 : le champ revient donc à zéro. Cette décision convient à l’état numérique actuel du projet ; une gestion distincte d’une saisie vide nécessiterait de faire évoluer son type, ce qui n’est pas l’objectif de cette leçon.
À retenir
- Un champ contrôlé reçoit sa valeur depuis l’état React avec `value`.
- `onChange` permet de réagir à une modification du champ.
- Typez l’événement avec `ChangeEvent` pour un champ de saisie.
- Convertissez la valeur textuelle en nombre avant de la stocker dans un état numérique.
Dans la prochaine leçon, vous relierez la soumission du formulaire à l’ajout d’une dépense dans la liste.