paint-brush
Comment simplifier la gestion de l'état avec l'API contextuelle React.js - Un didacticielpar@codebucks
Nouvelle histoire

Comment simplifier la gestion de l'état avec l'API contextuelle React.js - Un didacticiel

par CodeBucks11m2024/08/02
Read on Terminal Reader

Trop long; Pour lire

Ce blog propose un guide complet sur la gestion de l'état dans React à l'aide de l'API Context. Il explique comment éviter le perçage d'accessoires, améliorer les performances et implémenter efficacement l'API Context. Avec des exemples pratiques et des conseils d'optimisation, il est parfait pour les développeurs cherchant à rationaliser la gestion des états dans leurs applications React.
featured image - Comment simplifier la gestion de l'état avec l'API contextuelle React.js - Un didacticiel
CodeBucks HackerNoon profile picture
0-item

Bonjour👋🏻,


Cet article est spécialement créé pour les débutants désireux d'apprendre des méthodes plus efficaces pour gérer l'état entre plusieurs composants. Il vise également à résoudre le problème courant du perçage d'accessoires, qui peut rendre votre code plus difficile à maintenir et à comprendre. Commençons par quel type de problème l'API de contexte résout.


Si vous préférez le format vidéo, alors voici le tutoriel que vous pouvez visionner sur ma chaîne YouTube.👇🏻


Qu’est-ce que le forage d’hélices ?

Vous savez que parfois vous devez transmettre des données d'un composant parent à un composant enfant, et vous finissez par transmettre des accessoires à travers un tas de composants intermédiaires ? C'est ce qu'on appelle le forage d'hélices , et cela peut vite devenir compliqué. Passons en revue un exemple pour clarifier cela.


Forage d'accessoires dans React.js

Comme le montre le diagramme, imaginez que vous avez récupéré des données dans le composant App , qui se trouve à la racine de votre application. Désormais, si un composant profondément imbriqué, par exemple le composant Grandchild , a besoin d'accéder à ces données, vous le transmettez généralement via les composants Parent et Child en tant qu'accessoires avant qu'ils n'atteignent Grandchild . Cela peut devenir moche à mesure que votre application se développe.


Voici une autre représentation visuelle :


Exemple de forage d'accessoires Reactjs

Dans l'exemple ci-dessus, le composant Profile a besoin de données utilisateur, mais ces données doivent d'abord transiter par les composants App et Navigation , même si ces composants intermédiaires n'utilisent pas les données eux-mêmes. Alors, comment pouvons-nous nettoyer cela ? C'est là que l'API Context s'avère utile.


Forage d'accessoires :

  • Augmente le rendu des composants
  • Augmente le code passe-partout
  • Crée une dépendance de composant
  • Diminue les performances

API de contexte de réaction

L'API contextuelle dans React.js vous permet de transmettre des données entre composants sans avoir besoin de les transmettre en tant qu'accessoires à chaque niveau de l'arborescence des composants. Il fonctionne comme un système de gestion d'état global dans lequel vous définissez votre état dans un objet contextuel, puis vous pouvez facilement y accéder n'importe où dans l'arborescence des composants. Comprenons cela avec un exemple.


API contextuelle React.js

Comme vous pouvez le voir sur le diagramme, nous avons un objet contextuel qui stocke les données auxquelles plusieurs composants peuvent accéder. Ces données sont récupérées à partir d'API ou de services tiers. Avant d'accéder à ces données de contexte dans n'importe quel composant, nous devons envelopper tous les composants qui nécessitent ces données dans un composant fournisseur de contexte.


Si nous avons uniquement besoin d'accéder aux données des composants de navigation et de profil, nous n'avons pas besoin de terminer le composant d'application. Une fois que vous avez encapsulé les composants pertinents avec ContextProvider , vous pouvez accéder directement aux données contextuelles dans n'importe quel composant qui les consomme. Ne vous inquiétez pas si vous ne le comprenez toujours pas ; Plongeons dans le code et voyons-le en action.


Comment utiliser l'API contextuelle ?

Tout d'abord, créons une application React à l'aide de Vite.js . Copiez simplement les commandes suivantes pour configurer le projet.


 npm create vite@latest


  • Ajoutez le nom de votre projet
  • Sélectionnez Réagir
  • Sélectionnez dactylographié parmi les options
 cd project_name // to change to project directory npm install npm run dev


Ensuite, vous pouvez ouvrir votre serveur de développement http://localhost:5173 dans votre navigateur.


Commençons par créer les dossiers requis. Voici la structure des dossiers de notre projet.

 src | components | context


Dans le dossier des composants, créons le fichier Profile.jsx et ajoutons le code suivant.

 import React from 'react' const Profile = () => { return ( <div>Profile</div> ) } export default Profile


Créez un composant supplémentaire appelé Navbar.jsx dans le dossier des composants.

 import Profile from './Profile' const Navbar = () => { return ( <nav style={{ display: "flex", justifyContent: "space-between", alignItems: "center", width: "90%", height: "10vh", backgroundColor: theme === "light" ? "#fff" : "#1b1b1b", color: theme === "light" ? "#1b1b1b" : "#fff", border: "1px solid #fff", borderRadius: "5px", padding: "0 20px", marginTop: "40px", }}> <h1>LOGO</h1> <Profile /> </nav> ) } export default Navbar


Importons ce composant <Navbar /> dans le fichier App.jsx .

 import Navbar from "./components/Navbar"; function App() { return ( <main style={{ display: "flex", flexDirection: "column", justifyContent: "start", alignItems: "center", height: "100vh", width: "100vw", }} > <Navbar /> </main> ); } export default App;


Donc, fondamentalement, le composant <Profile /> est l'enfant de <Navbar /> et <Navbar /> est l'enfant du composant <App /> .

Ajout d'une API de contexte

Créons le fichier UserContext.jsx dans le dossier context . Ajoutez le code suivant au fichier.


 import { createContext, useEffect, useState } from "react"; export const UserContext = createContext(); export const UserProvider = ({ children }) => { const [user, setUser] = useState(null); const fetchUserData = async (id) => { const response = await fetch( `https://jsonplaceholder.typicode.com/users/${id}` ).then((response) => response.json()); console.log(response); setUser(response); }; useEffect(() => { fetchUserData(1); }, []); return ( <UserContext.Provider value={{ user, fetchUserData }} > {children} </UserContext.Provider> ); };


  • Tout d’abord, nous créons un objet UserContext vide en utilisant createContext . Nous veillons à l'importer depuis react . Nous pouvons ajouter des valeurs par défaut à l'intérieur de l'objet contextuel, mais nous le gardons nul pour l'instant.


  • Ensuite, nous créons UserProvider , qui renvoie un fournisseur utilisant UserContext , comme UserContext.Provider . Il entoure les composants enfants et, dans la valeur, nous pouvons transmettre tout ce que nous voulons utiliser dans les composants enfants.


  • À l'heure actuelle, nous utilisons l'API jsonplaceholder pour récupérer les données utilisateur. Le jsonplaceholder fournit de faux points de terminaison d'API à des fins de test. La fonction fetchUserData accepte id et utilise cet identifiant pour récupérer les données utilisateur. Ensuite, nous stockons la réponse dans l'état user .


  • Nous appelons la fonction fetchUserData dans useEffect donc lors du chargement de la page, elle appelle la fonction et injecte les données dans l'état user .


Utilisons maintenant ce contexte dans le composant <App /> . Enveloppez le composant <NavBar /> à l'aide du <UserProvider /> ; le même que le code suivant :

 <UserProvider> <Navbar /> </UserProvider>


Utilisons l'état user dans le composant <Profile /> . Pour cela, nous utiliserons le hook useContext . Cela prend UserContext et fournit les valeurs que nous avons transmises dans UserProvider telles que l'état user et la fonction fetchUserData . N'oubliez pas que nous n'avons pas besoin d'encapsuler le composant <Profile /> puisqu'il se trouve déjà dans le composant <Navbar /> qui est déjà encapsulé avec le fournisseur.


Ouvrez le Profile.jsx et ajoutez le code suivant.

 const { user } = useContext(UserContext); if (user) { return ( <span style={{ fontWeight: "bold", }} > {user.name} </span> ); } else { return <span>Login</span>; }


Ici, nous utilisons l'état user du UserContext . Nous afficherons le nom d'utilisateur s'il y a user , sinon nous afficherons juste un message de connexion. Maintenant, si vous voyez le résultat, il devrait y avoir un nom d'utilisateur dans le composant de la barre de navigation. C'est ainsi que nous pouvons utiliser directement n'importe quel état dans le contexte de n'importe quel composant. Le composant qui utilise cet état doit être encapsulé dans <Provider /> .


Vous pouvez également utiliser plusieurs contextes. Il vous suffit d'envelopper les composants du fournisseur dans un autre composant du fournisseur, comme indiqué dans l'exemple suivant.

 <ThemeProvider> <UserProvider> <Navbar /> </UserProvider> </ThemeProvider>


Dans l'exemple ci-dessus, nous utilisons <ThemeProvider /> qui gère l'état du thème.


Vous pouvez regarder la vidéo YouTube ci-dessus pour voir l'exemple complet d'utilisation de plusieurs fournisseurs de contexte.

Optimisation du rendu dans l'API React Context

Un problème se produit lorsque vous utilisez l'API Context dans plusieurs composants. Chaque fois que l'état ou la valeur change dans l'API de contexte, elle restitue tous les composants abonnés à ce contexte particulier, même si tous les composants n'utilisent pas l'état modifié. Pour comprendre ce problème de nouveau rendu, créons un composant <Counter /> qui utilise le contexte pour stocker et afficher les valeurs de comptage.


Consultez l’exemple suivant. Vous pouvez créer un fichier Counter.jsx dans le dossier des composants et coller le code suivant.


 import { createContext, memo, useContext, useState } from "react"; const CountContext = createContext(); const CountProvider = ({ children }) => { const [count, setCount] = useState(0); return ( <CountContext.Provider value={{ count, setCount }}> {children} </CountContext.Provider> ); }; function CountTitle() { console.log("This is Count Title component"); return <h1>Counter Title</h1>; } function CountDisplay() { console.log("This is CountDisplay component"); const { count } = useContext(CountContext); return <div>Count: {count}</div>; } function CounterButton() { console.log("This is CounterButton component"); const { count, setCount } = useContext(CountContext); return ( <> <CountTitle /> <CountDisplay /> <button onClick={() => setCount(count + 1)}>Increase</button> </> ); } export default function Counter() { return ( <CountProvider> <CounterButton /> </CountProvider> ); }


Dans le code ci-dessus :

  • Tout d’abord, nous créons un objet CountContext à l’aide createContext.


  • Dans CountProvider, nous avons un état pour stocker les valeurs de comptage. Nous envoyons count et la méthode setCount aux composants enfants via value prop.


  • Nous avons créé des composants séparément pour voir combien de fois les composants individuels sont restitués.

    • <CountTitle /> : Ce composant affiche uniquement le titre et n'utilise même aucune valeur du contexte.

    • <CountDisplay /> : ce composant affiche les valeurs de comptage et utilise l'état count du contexte.

    • <CounterButton /> : ce composant restitue à la fois le composant ci-dessus et un bouton qui augmente les valeurs de comptage à l'aide setCount .


  • À la fin, nous encapsulons le composant <CounterButton /> dans le composant CountProvider afin que les autres composants puissent accéder aux valeurs de comptage.


Maintenant, si vous exécutez le code et cliquez sur le bouton Increase , vous verrez dans les journaux que chaque composant est restitué à chaque fois que l'état change. Le <CountTitle /> n'utilise même pas de valeurs de comptage, mais il est en cours de rendu. Cela se produit parce que le composant parent de <CountTitle /> qui est <CounterButton /> utilise et met à jour la valeur de count et c'est pourquoi il est restitué.


Comment pouvons-nous optimiser ce comportement ? La réponse est memo . Le memo React vous permet d'éviter de restituer un composant lorsque ses accessoires sont inchangés. Après le composant <CountTitle /> , ajoutons la ligne suivante.


 const MemoizedCountTitle = React.memo(CountTitle)


Maintenant, dans le composant <CounterButton /> , où nous restituons le composant <CountTitle /> , remplacez le <CountTitle /> par <MemoizedCountTitle /> comme dans le code suivant :


 <> <MemoizedCountTitle /> <CountDisplay /> <button onClick={() => setCount(count + 1)}>Increase</button> </>


Maintenant, si vous augmentez le nombre et vérifiez les journaux, vous devriez pouvoir voir qu'il ne restitue plus le composant <CountTitle /> .

API Redux et Contexte

Redux est une bibliothèque de gestion d'état pour la gestion d'état complexe avec des transitions d'état plus prévisibles. Alors que l'API Context est conçue pour une gestion simple de l'état et la transmission de données via l'arborescence des composants sans perçage d'accessoires. Alors, quand choisir lequel ?


  • Utilisez l'API React Context pour une gestion d'état simple et localisée où l'état ne change pas fréquemment.


  • Utilisez Redux pour les besoins complexes de gestion d'état, en particulier dans les applications plus volumineuses où les avantages de sa gestion d'état structurée l'emportent sur la configuration supplémentaire.


Il existe également une autre bibliothèque, qui constitue également une option populaire pour la gestion de l'État. Le recul de réaction .


  • React Recoil est une bibliothèque de gestion d'état pour React qui vise à fournir la simplicité de l'API Context avec la puissance et les performances de Redux.


Si vous souhaitez en savoir plus sur React Recoil , faites-le-moi savoir dans les commentaires et je créerai des didacticiels approfondis sur ce sujet en fonction de vos commentaires.

Conclusion

L'API contextuelle React.js offre un moyen puissant et efficace de gérer les états de plusieurs composants, résolvant ainsi efficacement le problème du forage d'accessoires. En utilisant l'API Context, vous pouvez simplifier votre code, réduire les rendus inutiles et améliorer les performances globales des applications.


Bien que l'API Context soit idéale pour une gestion d'état simple, des applications plus complexes peuvent bénéficier de l'utilisation Redux ou d'autres bibliothèques de gestion d'état comme React Recoil . Comprendre quand et comment utiliser ces outils vous permettra de créer des applications React plus maintenables et évolutives.


Merci d'avoir lu cet article, j'espère que vous l'avez trouvé utile. Si vous souhaitez apprendre et créer des projets à l'aide de React, Redux et Next.js, vous pouvez visiter ma chaîne YouTube ici : CodeBucks


Voici mes autres articles que vous aimeriez peut-être lire :

Visitez mon blog personnel : DevDreaming