La création globale des états peut ralentir les performances de votre application. Découvrez comment créer et utiliser efficacement des états dans votre application React.

Si vous avez écrit beaucoup de code React, il est probable que vous ayez utilisé l'état de manière incorrecte. Une erreur courante commise par de nombreux développeurs React consiste à stocker les états globalement dans l'application, au lieu de les stocker dans les composants où ils sont utilisés.

Découvrez comment vous pouvez refactoriser votre code pour utiliser l'état local et pourquoi cela est toujours une bonne idée.

Exemple de base d'état dans React

Voici un très demande de compteur simple qui illustre la façon dont l'état est généralement géré dans React :

importer {useState} depuis'réagir'
importer {Comptoir} depuis'comptoir'

fonctionApplication(){
constante [count, setCount] = useState(0)
retour<Comptoircompter={compter}setCount={setCount} />
}

exporterdéfaut Application

Aux lignes 1 et 2, vous importez le useState() crochet pour créer l'état, et le

Comptoir composant. Vous définissez le compter état et setCount méthode de mise à jour de l'état. Ensuite, vous passez les deux à la Comptoir composant.

Le Comptoir le composant rend ensuite le compter et appels setCount pour incrémenter et décrémenter le compte.

fonctionComptoir({count, setCount}) {
retour (

Vous n'avez pas défini le compter variables et setCount fonctionner localement à l'intérieur du Comptoir composant. Au lieu de cela, vous l'avez transmis à partir du composant parent (Application). En d'autres termes, vous utilisez un état global.

Le problème des états globaux

Le problème avec l'utilisation d'un état global est que vous stockez l'état dans un composant parent (ou parent d'un parent), puis le transmettre comme accessoire au composant où cet état est réellement nécessaire.

Parfois, cela convient lorsque vous avez un état partagé par de nombreux composants. Mais dans ce cas, aucun autre composant ne se soucie de la compter état à l'exception de la Comptoir composant. Par conséquent, il est préférable de déplacer l'état vers le Comptoir composant où il est réellement utilisé.

Déplacement de l'état vers le composant enfant

Lorsque vous déplacez l'état vers le Comptoir composant, il ressemblerait à ceci :

importer {useState} depuis'réagir'

fonctionComptoir() {
constante [count, setCount] = useState(0)
retour (


Puis à l'intérieur de votre Application composant, vous n'avez rien à transmettre au Comptoir composant:

// importe
fonctionApplication(){
retour<Comptoir />
}

Le compteur fonctionnera exactement comme avant, mais la grande différence est que tous vos états sont localement à l'intérieur de ce Comptoir composant. Donc, si vous avez besoin d'un autre compteur sur la page d'accueil, vous aurez alors deux compteurs indépendants. Chaque compteur est autonome et prend soin de l'ensemble de son propre état.

Gestion de l'état dans des applications plus complexes

Une autre situation où vous utiliseriez un état global concerne les formulaires. Le Application Le composant ci-dessous transmet les données du formulaire (e-mail et mot de passe) et la méthode de configuration au Formulaire de connexion composant.

importer { useState } depuis"réagir";
importer { Formulaire de connexion } depuis"./Formulaire de connexion";

fonctionApplication() {
constante [formData, setFormData] = useState({
e-mail: "",
mot de passe: "",
});

fonctionmettre à jour les données du formulaire(nouvelles données) {
setFormData((précédent) => {
retour { ...prev, ...newData } ;
});
}

fonctiononSubmit() {
console.log (formData);
}

retour (
données={formData}
updateData={updateFormData}
onSubmit={onSubmit}
/>
);
}

Le Formulaire de connexion Le composant prend les informations de connexion et les restitue. Lorsque vous soumettez le formulaire, il appelle le mettre à jour les données fonction qui est également transmise depuis le composant parent.

fonctionFormulaire de connexion({ onSubmit, data, updateData }) {
fonctiongérerSoumettre(e) {
e.preventDefault();
onSubmit();
}

retour (


Plutôt que de gérer l'état sur le composant parent, il est préférable de déplacer l'état vers LoginForm.js, où vous utiliserez le code. Cela rend chaque composant autonome et ne dépend pas d'un autre composant (c'est-à-dire le parent) pour les données. Voici la version modifiée du Formulaire de connexion:

importer { useRef } depuis"réagir";

fonctionFormulaire de connexion({ onSubmit }) {
constante emailRef = useRef();
constante passwordRef = useRef();

fonctiongérerSoumettre(e) {
e.preventDefault();
onSubmit({
email: emailRef.current.value,
mot de passe: passwordRef.current.value,
});
}

retour (


Ici, vous liez l'entrée à une variable en utilisant réf attributs et les useRef React hook, plutôt que de transmettre directement les méthodes de mise à jour. Cela vous aide à supprimer le code verbeux et optimiser les performances du formulaire à l'aide du hook useRef.

Dans le composant parent (App.js), vous pouvez supprimer à la fois l'état global et updateFormData() méthode car vous n'en avez plus besoin. La seule fonction restante est onSubmit(), que vous invoquez depuis l'intérieur du Formulaire de connexion composant pour enregistrer les informations de connexion sur la console.

fonctionApplication() {
fonctiononSubmit(Données de formulaire) {
console.log (formData);
}

retour (
données={formData}
updateData={updateFormData}
onSubmit={onSubmit}
/>
);
}

Non seulement vous avez rendu votre état aussi local que possible, mais vous avez en fait supprimé le besoin de tout état (et utilisé réfs plutôt). Alors votre Application composant est devenu beaucoup plus simple (n'ayant qu'une seule fonction).

Ton Formulaire de connexion Le composant est également devenu plus simple car vous n'avez pas eu à vous soucier de la mise à jour de l'état. Au lieu de cela, vous gardez simplement une trace de deux réfs, et c'est tout.

Gestion de l'état partagé

Il y a un problème avec l'approche qui consiste à essayer de rendre l'État aussi local que possible. Vous rencontrez souvent des scénarios dans lesquels le composant parent n'utilise pas l'état, mais le transmet à plusieurs composants.

Un exemple est d'avoir un TodoContainer composant parent avec deux composants enfants: Liste de choses à faire et TodoCount.

fonctionTodoContainer() {
constante [todos, setTodos] = useState([])

retour (
<>


</>
)
}

Ces deux composants enfants nécessitent le todos état, donc TodoContainer le passe à tous les deux. Dans des scénarios comme ceux-ci, vous devez rendre l'état aussi local que possible. Dans l'exemple ci-dessus, en le plaçant à l'intérieur du TodosContainer est aussi local que possible.

Si vous deviez mettre cet état dans votre Application composant, il ne serait pas aussi local que possible car ce n'est pas le parent le plus proche des deux composants qui ont besoin des données.

Pour les applications volumineuses, la gestion de l'état uniquement avec le useState() crochet peut s'avérer difficile. Dans de tels cas, vous devrez peut-être opter pour le API de contexte de réaction ou Réagir Redux pour gérer efficacement l'État.

En savoir plus sur les crochets React

Les crochets constituent la base de React. En utilisant des crochets dans React, vous pouvez éviter d'écrire un code long qui utiliserait autrement des classes. Le crochet useState() est incontestablement le crochet React le plus couramment utilisé, mais il en existe de nombreux autres tels que useEffect(), useRef() et useContext().

Si vous cherchez à maîtriser le développement d'applications avec React, vous devez savoir comment utiliser ces crochets dans votre application.