Ajouter de l’interactivité
Certaines choses à l’écran se mettent à jour en réponse aux actions de l’utilisateur. Par exemple, en cliquant sur une galerie d’images, l’image active change. En React, les données qui changent au fil du temps sont appelées état. Vous pouvez ajouter un état à n’importe quel composant et le mettre à jour quand nécessaire. Dans ce chapitre, vous apprendrez à écrire des composants qui gèrent des interactions, mettent à jour leur état et ajustent leur affichage au fil du temps.
Dans ce chapitre
- Comment gérer les événements initiés par l’utilisateur
- Comment faire en sorte que les composants « se souviennent » des informations grâce aux états
- Comment React met à jour l’interface utilisateur (UI) en deux phases
- Pourquoi l’état ne se met pas à jour immédiatement après sa modification
- Comment cumuler plusieurs mises à jour d’un même état
- Comment mettre à jour un objet dans l’état
- Comment mettre à jour un tableau dans l’état
Réagir aux événements
React vous permet d’ajouter des gestionnaires d’événements à votre JSX. Les gestionnaires d’événements sont vos propres fonctions qui seront déclenchées en réponse aux interactions de l’utilisateur telles que des clics, survols, activations de champs de saisie de formulaires, etc.
Les composants natifs tels que <button>
ne prennent en charge que les événements natifs du navigateur tels que onClick
. Cependant, vous pouvez également créer vos propres composants et donner à leurs props de gestionnaires d’événements des noms spécifiques à l’application, selon vos besoins.
Error
Extra 185 of 186 byte(s) found at buffer[1]
Prêt·e à en apprendre davantage ?
Lisez Réagir aux événements pour apprendre comment ajouter des gestionnaires d’événements.
En savoir plusL’état : la mémoire d’un composant
Les composants ont souvent besoin de modifier ce qui est affiché à l’écran en réponse à une interaction. Par exemple, saisir du texte dans un formulaire devrait mettre à jour le champ de saisie, cliquer sur « suivant » dans un carrousel d’images devrait changer l’image affichée, cliquer sur « acheter » ajoute un produit au panier d’achats. Les composants ont besoin de « se souvenir » de certaines choses : la valeur saisie, l’image active, le panier d’achats. En React, ce type de mémoire spécifique au composant est appelé état.
Vous pouvez ajouter un état à un composant avec un Hook useState
. Les Hooks sont des fonctions spéciales qui permettent à vos composants d’utiliser des fonctionnalités de React (l’état en est une). Le Hook useState
vous permet de déclarer une variable d’état. Il prend l’état initial en argument et renvoie une paire de valeurs : l’état actuel et une fonction qui vous permet de le modifier.
const [index, setIndex] = useState(0);
const [showMore, setShowMore] = useState(false);
Voici comment une galerie d’images utilise et met à jour l’état lors d’un clic :
import { useState } from 'react'; import { sculptureList } from './data.js'; export default function Gallery() { const [index, setIndex] = useState(0); const [showMore, setShowMore] = useState(false); const hasNext = index < sculptureList.length - 1; function handleNextClick() { if (hasNext) { setIndex(index + 1); } else { setIndex(0); } } function handleMoreClick() { setShowMore(!showMore); } let sculpture = sculptureList[index]; return ( <> <button onClick={handleNextClick}> Suivant </button> <h2> <i>{sculpture.name} </i> par {sculpture.artist} </h2> <h3> ({index + 1} sur {sculptureList.length}) </h3> <button onClick={handleMoreClick}> {showMore ? 'Masquer' : 'Afficher'} les détails </button> {showMore && <p>{sculpture.description}</p>} <img src={sculpture.url} alt={sculpture.alt} /> </> ); }
Prêt·e à en apprendre davantage ?
Lisez L’état : la mémoire d’un composant pour apprendre comment mémoriser une valeur et la mettre à jour lors d’une interaction.
En savoir plusRendu et Commit
Avant que vos composants ne soient affichés à l’écran, React doit effectuer leur rendu. Comprendre les étapes de ce processus vous aidera à réfléchir à l’exécution de votre code et à expliquer son comportement.
Imaginez que vos composants soient des cuisiniers dans un restaurant, assemblant des plats savoureux à partir d’ingrédients. Dans ce scénario, React est le serveur qui prend les commandes des clients et leur apporte leurs plats. Ce processus de demande et de service de l’UI comporte trois étapes :
- Déclencher un rendu (envoyer la commande du client à la cuisine)
- Faire le rendu du composant (préparer la commande en cuisine)
- Mettre à jour le DOM (phase de Commit ; revient à déposer la commande sur la table du client)
Illustré par Rachel Lee Nabors
Prêt·e à en apprendre davantage ?
Lisez Rendu et Commit pour apprendre sur le cycle de vie d’une mise à jour de l’interface.
En savoir plusL’état est un instantané
Contrairement aux variables JavaScript classiques, une variable d’état dans React se comporte davantage comme une photo instantanée. Lui affecter une nouvelle valeur ne change pas la variable d’état que vous avez déjà, mais déclenche plutôt un nouveau rendu. Ça peut surprendre au début !
console.log(count); // 0
setCount(count + 1); // Entraînera un nouveau rendu avec la valeur 1
console.log(count); // Toujours 0 !
Ce comportement vous aide à éviter des bugs subtils. Voici une petite appli de discussion. Essayez de deviner ce qui se passe si vous appuyez sur « Envoyer » d’abord, et ensuite changez le destinataire pour Bob. Quel nom apparaîtra dans le alert
cinq secondes plus tard ?
import { useState } from 'react'; export default function Form() { const [to, setTo] = useState('Alice'); const [message, setMessage] = useState('Hello'); function handleSubmit(e) { e.preventDefault(); setTimeout(() => { alert(`Vouz avez dit ${message} à ${to}`); }, 5000); } return ( <form onSubmit={handleSubmit}> <label> À :{' '} <select value={to} onChange={e => setTo(e.target.value)}> <option value="Alice">Alice</option> <option value="Bob">Bob</option> </select> </label> <textarea placeholder="Message" value={message} onChange={e => setMessage(e.target.value)} /> <button type="submit">Envoyer</button> </form> ); }
Prêt·e à en apprendre davantage ?
Lisez L’état comme un instantané pour comprendre pourquoi un état semble « fixe » et immuable à l’intérieur des gestionnaires d’événements.
En savoir plusCumuler les mises à jour d’un même état
Ce composant comporte un bug : cliquer sur « +3 » n’incrémente le score qu’une seule fois.
import { useState } from 'react'; export default function Counter() { const [score, setScore] = useState(0); function increment() { setScore(score + 1); } return ( <> <button onClick={() => increment()}>+1</button> <button onClick={() => { increment(); increment(); increment(); }}>+3</button> <h1>Score: {score}</h1> </> ) }
L’état comme un instantané en explique la raison. Affecter une nouvelle valeur à un état déclenchera un nouveau rendu, mais ne change pas sa valeur dans le code en cours d’exécution. Ainsi, score
reste à 0
juste après avoir appelé setScore(score + 1)
.
console.log(score); // 0
setScore(score + 1); // setScore(0 + 1);
console.log(score); // 0
setScore(score + 1); // setScore(0 + 1);
console.log(score); // 0
setScore(score + 1); // setScore(0 + 1);
console.log(score); // 0
Vous pouvez corriger ça en passant une fonction de mise à jour lorsque vous affectez une nouvelle valeur à l’état. Voyez comme le remplacement de setScore(score + 1)
par setScore(s => s + 1)
corrige le bouton « +3 ». Ça vous permet de cumuler plusieurs mises à jour d’un même état.
import { useState } from 'react'; export default function Counter() { const [score, setScore] = useState(0); function increment() { setScore(s => s + 1); } return ( <> <button onClick={() => increment()}>+1</button> <button onClick={() => { increment(); increment(); increment(); }}>+3</button> <h1>Score: {score}</h1> </> ) }
Prêt·e à en apprendre davantage ?
Lisez Cumuler les série de mises à jour d’un même état pour apprendre comment cumuler plusieurs mises à jour d’une même variable d’état.
En savoir plusMettre à jour les objets d’un état
Un état peut contenir n’importe quel type de valeur JavaScript, y compris des objets. Cependant, vous ne devez pas changer directement les objets et les tableaux que vous stockez dans l’état React. Au lieu de cela, lorsque vous voulez mettre à jour un objet ou un tableau, vous devez en créer un nouveau (ou faire une copie de l’existant), puis mettre à jour l’état pour utiliser cette copie.
Généralement, vous utiliserez la syntaxe de spread ...
pour copier les objets et les tableaux que vous souhaitez modifier. Par exemple, la mise à jour d’un objet imbriqué pourrait ressembler à ceci :
import { useState } from 'react'; export default function Form() { const [person, setPerson] = useState({ name: 'Niki de Saint Phalle', artwork: { title: 'Blue Nana', city: 'Hamburg', image: 'https://i.imgur.com/Sd1AgUOm.jpg', } }); function handleNameChange(e) { setPerson({ ...person, name: e.target.value }); } function handleTitleChange(e) { setPerson({ ...person, artwork: { ...person.artwork, title: e.target.value } }); } function handleCityChange(e) { setPerson({ ...person, artwork: { ...person.artwork, city: e.target.value } }); } function handleImageChange(e) { setPerson({ ...person, artwork: { ...person.artwork, image: e.target.value } }); } return ( <> <label> Nom : <input value={person.name} onChange={handleNameChange} /> </label> <label> Titre : <input value={person.artwork.title} onChange={handleTitleChange} /> </label> <label> Ville : <input value={person.artwork.city} onChange={handleCityChange} /> </label> <label> Image : <input value={person.artwork.image} onChange={handleImageChange} /> </label> <p> <i>{person.artwork.title}</i> {' par '} {person.name} <br /> (à {person.artwork.city}) </p> <img src={person.artwork.image} alt={person.artwork.title} /> </> ); }
Si la copie d’objets dans le code devient fastidieuse, vous pouvez utiliser une bibliothèque telle que Immer pour simplifier le code :
{ "dependencies": { "immer": "1.7.3", "react": "latest", "react-dom": "latest", "react-scripts": "latest", "use-immer": "0.5.1" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test --env=jsdom", "eject": "react-scripts eject" }, "devDependencies": {} }
Prêt·e à en apprendre davantage ?
Lisez Mettre à jour les objets d’un état pour apprendre comment mettre à jour correctement les objets d’une variable d’état.
En savoir plusMettre à jour les tableaux d’un état
Les tableaux sont un autre type d’objet modifiable en JavaScript que vous pouvez stocker dans un état et que vous devez traiter comme étant en lecture seule. Tout comme avec les objets, lorsque vous souhaitez mettre à jour un tableau stocké dans un état, vous devez en créer un nouveau (ou en copier un existant), puis affecter le nouveau tableau dans l’état :
import { useState } from 'react'; const initialList = [ { id: 0, title: 'Big Bellies', seen: false }, { id: 1, title: 'Lunar Landscape', seen: false }, { id: 2, title: 'Terracotta Army', seen: true }, ]; export default function BucketList() { const [list, setList] = useState( initialList ); function handleToggle(artworkId, nextSeen) { setList(list.map(artwork => { if (artwork.id === artworkId) { return { ...artwork, seen: nextSeen }; } else { return artwork; } })); } return ( <> <h1>Liste d’œuvres d’art</h1> <h2>Ma liste à voir absolument :</h2> <ItemList artworks={list} onToggle={handleToggle} /> </> ); } function ItemList({ artworks, onToggle }) { return ( <ul> {artworks.map(artwork => ( <li key={artwork.id}> <label> <input type="checkbox" checked={artwork.seen} onChange={e => { onToggle( artwork.id, e.target.checked ); }} /> {artwork.title} </label> </li> ))} </ul> ); }
Si la copie de tableaux dans le code devient fastidieuse, vous pouvez utiliser une bibliothèque telle que Immer pour simplifier le code :
{ "dependencies": { "immer": "1.7.3", "react": "latest", "react-dom": "latest", "react-scripts": "latest", "use-immer": "0.5.1" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test --env=jsdom", "eject": "react-scripts eject" }, "devDependencies": {} }
Prêt·e à en apprendre davantage ?
Lisez Mettre à jour les tableaux d’un état pour apprendre comment mettre à jour correctement les tableaux d’une variable d’état.
En savoir plusEt maintenant ?
Allez sur Réagir aux événements pour commencer à lire ce chapitre page par page !
Ou alors, si vous êtes déjà à l’aise avec ces sujets, pourquoi ne pas explorer comment gérer l’état ?