Tutoriel React, Partie 17: Cinquième étape du travail sur une application TODO, modification de l'état des composants

Dans la partie d'aujourd'hui de la traduction du cours React, nous vous suggérons de terminer la prochaine tâche pratique et de présenter à votre attention une histoire sur la façon de modifier l'état des composants React.

image

Partie 1: aperçu du cours, raisons de la popularité de React, ReactDOM et JSX
Partie 2: composants fonctionnels
Partie 3: fichiers composants, structure du projet
Partie 4: composants parent et enfant
Partie 5: début des travaux sur une application TODO, les bases du style
Partie 6: sur certaines fonctionnalités du cours, JSX et JavaScript
Partie 7: styles en ligne
Partie 8: poursuite des travaux sur l'application TODO, familiarité avec les propriétés des composants
Partie 9: propriétés des composants
Partie 10: Atelier sur l'utilisation des propriétés et du style des composants
Partie 11: génération de balisage dynamique et méthode des tableaux de cartes
Partie 12: atelier, troisième étape de travail sur une application TODO
Partie 13: composants basés sur les classes
Partie 14: atelier sur les composants basés sur les classes, état des composants
Partie 15: ateliers santé composante
Partie 16: quatrième étape de travail sur une application TODO, gestion d'événements
Partie 17: cinquième étape de travail sur une application TODO, modifiant l'état des composants
Partie 18: la sixième étape de travail sur une application TODO
Partie 19: méthodes du cycle de vie des composants
Partie 20: la première leçon de rendu conditionnel
Partie 21: deuxième leçon et atelier sur le rendu conditionnel
Partie 22: la septième étape des travaux sur une application TODO, téléchargement de données depuis des sources externes
Partie 23: première leçon sur l'utilisation des formulaires
Partie 24: Deuxième leçon sur les formulaires
Partie 25: Atelier sur l'utilisation des formulaires
Partie 26: architecture d'application, modèle de conteneur / composant
Partie 27: projet de cours

Leçon 31. Atelier. Application TODO. Étape numéro 5


Original

▍Emploi


Lors du lancement de notre application Todo, vous pouvez remarquer qu'une notification s'affiche dans la console qui indique que nous, après avoir configuré la propriété checked d'un élément dans le composant TodoItem , n'avons pas fourni de mécanisme pour interagir avec cet élément sous la forme d'un onChange événements onChange . Lorsque vous travaillez avec l'interface d'application, cela se traduit par le fait que les indicateurs affichés sur la page ne peuvent pas être cochés ou décochés.

Ici, vous êtes invité à équiper un élément du type checkbox du composant TodoItem d'un gestionnaire d'événements onChange, qui, à ce stade du travail, est suffisant pour se présenter sous la forme d'une fonction qui renvoie quelque chose à la console.

▍Solution


Voici à quoi ressemble le code du composant TodoItem maintenant, qui est stocké dans le fichier TodoItem.js :

 import React from "react" function TodoItem(props) {   return (       <div className="todo-item">           <input type="checkbox" checked={props.item.completed}/>           <p>{props.item.text}</p>       </div>   ) } export default TodoItem 

C'est ce que la console affiche au démarrage de l'application.


Notification de la console

En même temps, les drapeaux ne répondent pas à nos effets.

Afin de se débarrasser de cette notification et de préparer le projet pour d'autres travaux, il suffit d'attribuer un onChange événements onChange à l'élément de checkbox à checkbox . Voici à quoi cela ressemble dans le code:

 import React from "react" function TodoItem(props) {   return (       <div className="todo-item">           <input               type="checkbox"               checked={props.item.completed}               onChange={() => console.log("Changed!")}           />           <p>{props.item.text}</p>       </div>   ) } export default TodoItem 

Ici, en tant que gestionnaire, nous utilisons une fonction simple qui génère le mot Checked! sur la console Checked! . Dans le même temps, cliquer sur les drapeaux n'entraîne pas de changement dans leur état, mais la notification de la console, comme on peut le voir sur la figure suivante, disparaît.


Les indicateurs ne fonctionnent toujours pas, mais la notification de la console a disparu

Cette petite modification apportée à l'application nous permettra, après avoir traité la modification de l'état des composants, de faire fonctionner correctement les cases à cocher.

Leçon 32. Modification de l'état des composants


Original

Commençons par une application standard créée à l'aide de create-react-app App.js create-react-app , dans le fichier App.js qui contient le code suivant:

 import React from "react" class App extends React.Component {   constructor() {       super()       this.state = {           count: 0       }   }     render() {       return (           <div>               <h1>{this.state.count}</h1>               <button>Change!</button>           </div>       )   } } export default App 

Le index.css styles index.css , qui est index.js dans le fichier index.js , contient la description des styles suivante:

 div {   display: flex;   flex-direction: column;   align-items: center;   justify-content: center; } h1 {   font-size: 3em; } button {   border: 1px solid lightgray;   background-color: transparent;   padding: 10px;   border-radius: 4px;  } button:hover {   cursor: pointer; } button:focus {   outline:0; } 

À ce stade, l'application ressemble à celle illustrée dans la figure suivante.


Page d'application dans le navigateur

Aujourd'hui, nous allons parler de la façon de changer l'état des composants. Si le composant a un état, cela permet, en l'initialisant, d'y stocker des données. Mais si l'état ne pouvait pas être changé, le composant ne bénéficierait pas particulièrement de sa présence, le stockage des données ne serait pas très différent, par exemple, de leur copie papier dans le code du composant.

Parlons de l'application, sur l'exemple dont nous allons envisager de travailler avec l'état du composant. Le composant App dont le code est présenté ci-dessus est un composant basé sur une classe. C'est assez évident, car nous avons besoin de ce composant pour avoir un état. Dans le code du composant, nous utilisons le constructeur.

Dans ce document, nous appelons, comme toujours, la méthode super() et initialisons l'état en lui écrivant la propriété count et en lui affectant une valeur initiale de 0 . Dans la méthode render() , nous imprimons un en-tête de premier niveau représentant la valeur de la propriété count partir de l'état du composant, ainsi qu'un bouton avec le mot Change! . Tout cela est formaté à l'aide de styles.

Si, à ce stade du travail sur l'application, ouvrez-la dans un navigateur et cliquez sur le bouton, alors, bien sûr, rien ne se passera. Mais nous devons cliquer sur le bouton pour changer l'état du composant, affectant sa propriété count . Dans le même temps, nous avons déjà étudié la méthodologie de gestion des événements dans React, et notre tâche est de créer un mécanisme qui, en répondant à un clic sur un bouton, modifie la propriété d'état de count .

Passons à la résolution de notre problème en équipant le bouton d'un onClick événements onClick , qui, pour commencer, produira simplement quelque chose sur la console.

Pour ce faire, nous allons ajouter une nouvelle méthode à la classe de composants. Vous pouvez l'appeler comme bon vous semble, mais il est d'usage d'appeler de telles méthodes pour que leurs noms indiquent les événements qu'elles traitent. Par conséquent, comme nous allons l'utiliser pour traiter l'événement click , nous l'appelons handleClick() . Voici à quoi ressemblera maintenant le code du composant App .

 import React from "react" class App extends React.Component {   constructor() {       super()       this.state = {           count: 0       }   }     handleClick() {       console.log("I'm working!")   }     render() {       return (           <div>               <h1>{this.state.count}</h1>               <button onClick={this.handleClick}>Change!</button>           </div>       )   } } export default App 

Veuillez noter qu'en faisant référence à cette méthode à partir de render() , nous utilisons une construction du formulaire this.handleClick .

Maintenant, si vous cliquez sur le bouton, le message correspondant apparaîtra dans la console.


Cliquer sur le bouton appelle la méthode de classe.

Maintenant, faisons en sorte que cliquer sur le bouton augmente le nombre affiché au-dessus, c'est-à-dire modifier l'état du composant. Essayez peut-être de changer directement l'état du composant, dans la méthode handleClick() ? Disons que si nous réécrivons cette méthode comme ceci:

 handleClick() {   this.state.count++ } 

Je dois dire tout de suite que cela ne fonctionne pas avec l'état des composants dans React. Tenter d'exécuter un tel code générera une erreur.

L'état du composant peut être comparé aux vêtements qu'une personne porte. S'il veut changer de vêtements, il ne modifie pas ou ne repeint pas les vêtements sans se retirer, mais l'enlève et met autre chose. En fait, c'est exactement ainsi qu'ils fonctionnent avec l'état des composants.

Vous vous souvenez peut-être que nous parlions d'une méthode spéciale utilisée pour modifier l'état, disponible dans les composants basés sur les classes car ils étendent la classe React.Component . Il s'agit de la méthode setState() . Il est utilisé dans les cas où vous devez modifier l'état d'un composant. Cette méthode peut être utilisée de différentes manières.

Rappelons qu'un état est un objet. Essayons de passer à la méthode setState() un objet qui remplacera l'état. Nous handleClick() méthode handleClick() ceci:

 handleClick() {   this.setState({ count: 1 }) } 

Tenter d'utiliser cette méthode provoquera l'erreur suivante: TypeError: Cannot read property 'setState' of undefined . En fait, ce dont nous parlons maintenant suscite beaucoup de controverse parmi les développeurs de React, et maintenant je vais vous montrer un moyen très simple de résoudre ce problème, qui, à première vue, peut sembler inhabituel.

Le fait est qu'à chaque fois, en créant une méthode de classe ( handleClick() dans notre cas), dans laquelle il est prévu d'utiliser la méthode setState() , cette méthode doit y être associée. Cela se fait dans le constructeur. Le code du composant après cette modification ressemblera à ceci:

 import React from "react" class App extends React.Component {   constructor() {       super()       this.state = {           count: 0       }       this.handleClick = this.handleClick.bind(this)   }     handleClick() {       this.setState({ count: 1 })   }     render() {       return (           <div>               <h1>{this.state.count}</h1>               <button onClick={this.handleClick}>Change!</button>           </div>       )   } } export default App 

Maintenant, après avoir cliqué sur le bouton Change! le numéro 1 apparaîtra au-dessus, les messages d'erreur ne seront pas affichés.


Appuyer sur un bouton modifie l'état

Certes, le bouton s'est avéré être «ponctuel». Après le premier clic dessus, 0 passe à 1 , et si vous cliquez à nouveau dessus, rien ne se passera. En général, cela n'est pas surprenant. Le code appelé lorsque le bouton est cliqué fait son travail, chaque fois que vous changez l'état en un nouveau, cependant, après le premier clic sur le bouton, le nouvel état, dans lequel le numéro 1 est stocké dans la propriété count , ne diffère pas de l'ancien. Afin de résoudre ce problème, envisagez une autre façon de travailler avec la méthode setState() .

Si nous ne sommes pas intéressés par l'état précédent du composant, nous pouvons simplement passer un objet à cette méthode, qui remplacera l'état. Mais il arrive souvent que le nouvel état d'un composant dépend de l'ancien. Dans notre cas, cela signifie que, sur la base de la valeur de la propriété count , qui est stockée dans la version précédente de l'état, nous voulons ajouter 1 à cette valeur. Dans les cas où pour modifier l'état, vous devez être conscient de ce qui y était précédemment stocké, vous pouvez transmettre à la méthode setState() une fonction qui, en tant que paramètre, reçoit la version précédente de l'état. Vous pouvez nommer ce paramètre comme vous le souhaitez, dans notre cas ce sera prevState . L'achat de cette fonction ressemblera à ceci:

 handleClick() {   this.setState(prevState => {             }) } 

Vous pourriez penser que dans une telle fonction, il suffit de se référer simplement à l'état en utilisant une construction de la forme this.state , mais cette approche ne nous conviendra pas. Par conséquent, il est important que cette fonction accepte la version précédente de l'état du composant.

La fonction doit renvoyer une nouvelle version de l'état. Voici à quoi handleClick() méthode handleClick() pour handleClick() ce problème:

 handleClick() {   this.setState(prevState => {       return {           count: prevState.count + 1       }   }) } 

Notez que pour obtenir la nouvelle valeur de la propriété count , nous utilisons la construction count: prevState.count + 1 . Vous pourriez penser qu'une construction du count: prevState.count++ formulaires count: prevState.count++ , mais l'opérateur ++ count: prevState.count++ variable à laquelle il est appliqué, cela signifiera une tentative de modifier la version précédente de l'état, nous ne l'utilisons donc pas ici.

Le code complet du fichier composant à ce stade ressemblera à ceci:

 import React from "react" class App extends React.Component {   constructor() {       super()       this.state = {           count: 0       }       this.handleClick = this.handleClick.bind(this)   }     handleClick() {       this.setState(prevState => {           return {               count: prevState.count + 1           }       })   }       render() {       return (           <div>               <h1>{this.state.count}</h1>               <button onClick={this.handleClick}>Change!</button>           </div>       )   } } export default App 

Maintenant, chaque clic sur le bouton augmente la valeur du compteur.


Chaque clic sur le bouton augmente la valeur du compteur.

Ce que nous venons de découvrir nous ouvre de grandes opportunités dans le développement d'applications React.

Nous avons dit précédemment qu'un composant parent peut, via un mécanisme de propriété, transmettre des propriétés de son propre état aux composants enfants. Si React détecte un changement d'état du composant parent, il restitue le composant enfant auquel cet état est transmis. Cela ressemble à un appel à la méthode render() . Par conséquent, le composant enfant reflétera les nouvelles données stockées dans l'état du composant parent.

Résumé


Aujourd'hui, vous avez préparé l'application Todo pour poursuivre les travaux, et vous vous êtes également familiarisé avec les mécanismes utilisés dans React pour modifier l'état d'un composant. La prochaine fois, il vous sera demandé d'étendre les capacités de l'application de formation en utilisant ce que vous avez appris aujourd'hui.

Chers lecteurs! Que pensez-vous du fait que l'état des composants dans React ne peut pas être modifié directement sans utiliser des mécanismes spéciaux?

Source: https://habr.com/ru/post/fr439984/


All Articles