Fermer

janvier 13, 2020

Une introduction à l'API contextuelle de React


Dans cet article, vous apprendrez à utiliser l'API contextuelle de React qui vous permet de gérer les états d'application globaux dans vos applications React sans recourir au forage d'accessoires.

Pour ce didacticiel, vous devez avoir une bonne compréhension des crochets. Néanmoins, avant de commencer, je vais brièvement discuter de ce qu'ils sont et des crochets que nous utiliserons dans cet article.

D'après les React Docs :

" Crochets sont un nouvel ajout dans React 16.8. Ils vous permettent d'utiliser l'état et d'autres fonctionnalités de React sans écrire de classe. »

C'est essentiellement ce qu'est un hook React. Il nous permet d'utiliser l'état, les références et d'autres caractéristiques React dans nos composants fonctionnels.

Discutons des deux crochets que nous rencontrerons dans cet article.

Le useState Hook

Le useState hook nous permet d'utiliser l'état dans nos composants fonctionnels. Un crochet useState prend la valeur initiale de notre état comme seul argument et renvoie un tableau de deux éléments. Le premier élément est notre variable d'état et le deuxième élément est une fonction dans laquelle nous pouvons utiliser la mise à jour de la valeur de la variable d'état.

Jetons un coup d'œil à l'exemple suivant:

 import React, {useState} de "réagir";

fonction SampleComponent () {
   const [count, setCount] = useState (0);
}

Ici, count est notre variable d'état et sa valeur initiale est 0 tandis que setCount est une fonction que nous pouvons utiliser pour mettre à jour la valeur de count.

Le crochet useContext

J'en parlerai plus loin dans l'article mais ce crochet nous permet essentiellement de consommer la valeur d'un contexte. Ce que cela signifie en réalité apparaîtra plus loin dans l'article.

Espaces de travail Yarn

Les espaces de travail Yarn vous permettent d'organiser la base de code de votre projet à l'aide d'un référentiel monolithique (monorepo). React est un bon exemple de projet open source monorepo et utilise les espaces de travail Yarn pour atteindre cet objectif. En savoir plus →

Pourquoi avons-nous besoin de l'API de contexte?

Nous voulons créer un composant "basculeur de thème" qui bascule entre le mode clair et le mode sombre pour notre application React. Chaque composant doit avoir accès au mode de thème actuel pour pouvoir être stylisé en conséquence.

Normalement, nous fournissons le mode de thème actuel à tous les composants via des accessoires et mettons à jour le thème actuel en utilisant l'état :

 importez React depuis "react";
importer ReactDOM depuis "react-dom";

fonction App () {
  revenir (
    

{theme}

); } fonction Texte ({thème}) { revenir(   

{theme}

); } const rootElement = document.getElementById ("root"); ReactDOM.render (rootElement);

Dans l'exemple de code ci-dessus, nous avons créé un composant texte qui rend un élément h1 . La couleur de l'élément h1 dépend du mode de thème actuel. Actuellement, le thème est bleu. Nous pouvons basculer entre les thèmes bleu et rouge en utilisant l'état .

Nous allons créer un état appelé «thème» à l'aide de useState ] crochet. Le crochet useState renverra la valeur actuelle du thème et une fonction que nous pouvons utiliser pour mettre à jour le thème.

Alors, créons notre état de thème:

 const [theme, setTheme] = React .useState ("bleu");

Nous ajouterons également un élément bouton à notre composant App . Ce bouton sera utilisé pour basculer entre les thèmes et il a besoin d'un gestionnaire d'événements de clic. Alors, écrivons le gestionnaire d'événements click comme ceci:

 const onClickHandler = () => {
  setTheme ();
}

Maintenant, nous voulons définir le nouveau thème sur Rouge si le thème actuel est Bleu et vice versa. Au lieu d'utiliser une instruction if une méthode plus pratique consiste à utiliser l'opérateur ternaire en JavaScript.

 setTheme (theme === "red"? "Blue": "red ");

Alors maintenant, nous avons écrit notre gestionnaire onClick . Ajoutons cet élément de bouton au composant de l'application :

 

Modifions également la valeur des accessoires de thème du composant Text à l'état de thème.

 

Maintenant, nous devrions avoir ceci:

 importez React de "react";
importer ReactDOM depuis "react-dom";

import "./styles.css";


fonction App () {
  const [theme, setTheme] = React.useState ("rouge");

  const onClickHandler = () => {
  setTheme (theme === "red"? "blue": "red");
  }

  revenir (
    
); } fonction Texte ({thème}) { revenir(   

{theme}

); } const rootElement = document.getElementById ("root"); ReactDOM.render (rootElement);

Nous pouvons maintenant basculer entre nos deux thèmes. Cependant, s'il s'agissait d'une application beaucoup plus volumineuse, il serait difficile d'utiliser le thème dans des composants profondément imbriqués et le code deviendrait lourd.

Présentation de l'API contextuelle

Permettez-moi de vous présenter l'API contextuelle. Selon la documentation de React:

«Le contexte fournit un moyen de transmettre des données à travers l'arborescence des composants sans avoir à transmettre manuellement les accessoires à tous les niveaux.»

Pour une définition plus approfondie, il vous fournit un moyen pour rendre des données particulières disponibles pour tous les composants dans l'arborescence des composants, quelle que soit la profondeur d'imbrication de ce composant.

Voyons cet exemple:

 const App = () => {
  revenir(
    
  );
}

const ParentComponent = (props) => (
  
)

const Child = (accessoires) => (
  
)

const Petit-enfant = (accessoires) => (
  

Thème: {props.theme}

)

Dans l'exemple ci-dessus, nous avons spécifié le thème d'application à l'aide d'un accessoire dans le ParentComponent appelé thème . Nous avons dû transmettre ces accessoires à tous les composants dans l'arborescence des composants pour les obtenir là où ils sont nécessaires, à savoir le composant GrandChild . ChildComponent n'avait rien à voir avec les accessoires de thème mais était juste utilisé comme intermédiaire.

Maintenant, imaginez que le composant GrandChild était plus profondément imbriqué que dans l'exemple du haut . Il nous faudrait passer les accessoires thématiques de la même manière que nous l'avons fait ici, ce qui serait lourd. C'est le problème que Contexte résout. Avec Context chaque composant de l'arborescence des composants a accès aux données que nous décidons de mettre dans notre contexte.

Commençons par Context

Il est temps de répliquer le bouton de basculement de thème que nous avons créé au début de l'article avec l'API Context. Cette fois, notre bascule de thème sera un composant distinct. Nous allons créer un composant ThemeToggler qui change le thème de notre application React en utilisant le contexte .

Tout d'abord, initialisons notre application React. (Je préfère utiliser create-react-app mais vous pouvez utiliser la méthode que vous préférez.)

Une fois que vous avez initialisé votre projet React, créez un fichier appelé ThemeContext.js dans votre dossier / src . Vous pouvez également créer un dossier appelé / context et y placer votre fichier ThemeContext si vous le souhaitez.

Passons maintenant.

Création de votre API de contexte [19659008] Nous allons créer notre contexte de thème dans notre fichier ThemeContext.js .

Pour créer un contexte, nous utilisons React.createContext qui crée un objet de contexte. Vous pouvez transmettre n'importe quoi comme argument à React.createContext . Dans ce cas, nous allons passer une chaîne qui est le mode de thème actuel. Alors maintenant, notre mode de thème actuel est le mode de thème "léger".

 import React de "react";

const ThemeContext = React.createContext ("light");
exporter ThemeContext par défaut;

Pour rendre ce contexte accessible à tous nos composants React, nous devons utiliser un fournisseur. Qu'est-ce qu'un fournisseur? Selon la documentation de React, chaque objet de contexte est fourni avec un composant Provider React qui permet aux composants consommateurs de s'abonner aux changements de contexte. C'est le fournisseur qui permet au contexte d'être consommé par d'autres composants. Cela dit, créons notre fournisseur.

Accédez à votre fichier App.js . Pour créer notre fournisseur, nous devons importer notre ThemeContext .

Une fois que le ThemeContext a été importé, nous devons inclure le contenu de notre App ] dans ThemeContext.Provider et donnez au composant ThemeContext.Provider un accessoire appelé valeur qui contiendra les données que nous voulons mettre à la disposition de notre arborescence de composants .

 fonction App () {
  const theme = "light";
  revenir (
    
      
); }

Alors maintenant, la valeur de «lumière» est disponible pour tous nos composants (que nous écrirons bientôt).

Création de notre fichier de thème

Maintenant, nous allons créer notre fichier de thème qui contiendra les différentes valeurs de couleur pour nos thèmes clairs et sombres. Créez un fichier dans votre dossier / src appelé Colors.js .

Dans Colors.js nous allons créer un objet appelé AppTheme . Cet objet contiendra les couleurs de nos thèmes. Une fois que vous avez terminé, exportez l'objet AppTheme comme suit:

 const AppTheme = {
    lumière: {
        textColor: "# 000",
        backgroundColor: "#fff"
    },
    foncé: {
        textColor: "#fff",
        backgroundColor: "# 333"
    }
}

exporter AppTheme par défaut;

Il est maintenant temps de commencer à créer nos différents composants React.

Création de nos composants React

Créons les composants suivants:

  • Header
  • ThemeToggler
  • MainWithClass
 importez React à partir de "react ";
importer ThemeToggler à partir de "./ThemeToggler";

const headerStyles = {
    rembourrage: "1rem",
    affichage: "flex",
    justificationContenu: "espace entre",
    alignItems: "centre"
}
const Header = () => {
    revenir(
        

API de contexte

); } exporter l'en-tête par défaut;
ThemeToggler.jsx

(Pour l'instant, nous allons simplement renvoyer un div .) Vide

 import React from "react";
importer ThemeContext depuis "../Context/ThemeContext";

const themeTogglerStyle = {
    curseur: "pointeur"
}
const ThemeToggler = () => {
        revenir(
            
); } exporter ThemeToggler par défaut;

Consommation de contexte avec des composants basés sur les classes

Ici, nous utiliserons la valeur de notre ThemeContext . Comme vous le savez peut-être déjà, nous avons deux méthodes d'écriture de composants dans React : à travers des fonctions ou des classes. Le processus d'utilisation du contexte dans les deux méthodes est différent, nous allons donc créer deux composants pour servir de section principale de notre application: MainWithClass et MainWithFunction .

Commençons par MainWithClass .

MainWithClass.jsx

Nous devrons importer notre ThemeContext et AppTheme . Une fois cela fait, nous écrirons une classe qui retourne notre JSX à partir d'une méthode de rendu. Maintenant, nous devons consommer notre contexte. Il existe deux méthodes pour ce faire avec les composants basés sur les classes:

  1. La première méthode est via Class.contextType .

    Pour utiliser cette méthode, nous affectons l'objet contextuel à partir de notre ThemeContext à contextType propriété de notre classe. Après cela, nous pourrons accéder à la valeur de contexte en utilisant this.context . Vous pouvez également le référencer dans n'importe laquelle des méthodes de cycle de vie et même dans la méthode de rendu.

     import React, {Component} from "react";
    importer ThemeContext depuis "../Context/ThemeContext";
    importer AppTheme depuis "../Colors";
    
    classe Main étend Component {
        constructeur(){
            super();
        }
        static contextType = ThemeContext;
        rendre(){
            const currentTheme = AppTheme [this.context];
            revenir(
                
    );     } }

    Après avoir affecté ThemeContext à la propriété contextType de notre classe, j'ai enregistré l'objet de thème actuel dans la variable currentTheme .

    Maintenant, nous allons récupérez les couleurs de la variable currentTheme et utilisez-les pour styliser du balisage.

     render () {
            const currentTheme = AppTheme [this.context];
            revenir (
                

    Titre 1

    Ceci est un paragraphe

                

    C’est tout! Cette méthode, cependant, vous limite à consommer un seul contexte.

  2. La deuxième méthode est ThemeContext.Consumer qui implique l'utilisation d'un consommateur. Chaque objet de contexte est également livré avec un composant Consumer React qui peut être utilisé dans un composant basé sur une classe. Le composant consommateur prend un enfant en tant que fonction et cette fonction renvoie un nœud React. La valeur de contexte actuelle est passée à cette fonction en tant qu'argument.

    Maintenant, remplaçons le code dans notre composant MainWithClass par ceci:

     La classe Main étend Component {
        constructeur () {
            super();
            this.state = {
            }
        }
        rendre(){
                   revenir(
                        
                       {
                        (thème) => {
                            const currentTheme = AppTheme [theme];
                            revenir(
                                

    Titre 1

    Ceci est un paragraphe

    )                                             }                 }             
            );     } }

    Comme vous pouvez le voir, nous avons utilisé la valeur actuelle de notre ThemeContext que nous avons aliasé en tant que "thème" et nous avons saisi les valeurs de couleur pour ce mode de thème et l'avons affecté à la variable currentTheme . Avec cette méthode, vous pouvez utiliser plusieurs consommateurs.

Ce sont les deux méthodes de consommation de contexte avec des composants basés sur des classes.

Consommation de contexte avec des composants fonctionnels

La consommation de contexte avec des composants fonctionnels est plus facile et moins fastidieuse que de le faire donc avec des composants basés sur les classes. Pour consommer le contexte dans un composant fonctionnel, nous utiliserons un hook appelé useContext .

Voici à quoi ressemblerait la consommation de notre ThemeContext avec un composant fonctionnel:

 const Main = () => {
    const theme = useContext (ThemeContext);
    const currentTheme = AppTheme [theme];
    revenir(
        

Titre 1

Ceci est un paragraphe

); } exporter par défaut Main;

Comme vous pouvez le voir, tout ce que nous avions à faire était d'utiliser notre crochet useContext avec notre ThemeContext transmis en argument.

Remarque : Vous devez utiliser ces différents composants dans le fichier App.js pour voir les résultats.

Mise à jour de notre thème avec le composant ThemeToggler

Maintenant, nous allons travailler sur notre Composant ThemeToggler . Nous devons pouvoir basculer entre les thèmes clairs et sombres. Pour ce faire, nous allons devoir modifier notre ThemeContext.js . Notre React.createContext prendra maintenant un objet ressemblant au résultat d'un crochet useState comme argument.

 const ThemeContext = React.createContext (["light", () => {}]);

Nous avons passé un tableau à la fonction React.createContext . Le premier élément du tableau est le mode de thème actuel et le deuxième élément est la fonction qui serait utilisée pour mettre à jour le thème. Comme je l'ai dit, cela ressemble au résultat d'un crochet useState mais ce n'est pas exactement le résultat d'un crochet useState .

Nous allons maintenant modifier notre application . fichier js . Nous devons remplacer la valeur transmise au fournisseur par un hook useState . Maintenant, la valeur de notre contexte de thème est un crochet useState dont la valeur par défaut est "light".

 function App () {
  const themeHook = useState ("light");
  revenir (
    
      
); }

Écriture de notre composant ThemeToggler

Écrivons maintenant notre composant ThemeToggler :

 import React, {useContext} de "react";
importer ThemeContext depuis "../Context/ThemeContext";

const themeTogglerStyle = {
    curseur: "pointeur"
}
const ThemeToggler = () => {
    const [themeMode, setThemeMode] = useContext (ThemeContext);
    revenir(
        
{setThemeMode (themeMode === "light"? "Dark": "light")}}>                              {themeMode === "light"? "?": "☀️"}             
); } exporter ThemeToggler par défaut;

Puisque la valeur de notre contexte de thème est maintenant un crochet chaque fois que nous appelons useContext dessus, il retournera un tableau. En utilisant la déstructuration, nous avons pu récupérer les éléments du tableau. Nous avons ensuite écrit un gestionnaire d'événements onClick pour notre ThemeToggler . Avec ce code, chaque fois que l'on cliquera sur le basculeur de thème, il changera le thème de notre application.

Nous allons maintenant modifier les différentes versions de notre composant Main .

Modifier notre MainWithClass Component

  1. La version du composant MainWithClass qui utilise la méthode Class.contextType :
     import React, {Component} de "react";
    importer ThemeContext depuis "../Context/ThemeContext";
    importer AppTheme depuis "../Colors";
    
    classe Main étend Component {
        constructeur(){
            super();
        }
        static contextType = ThemeContext;
        rendre(){
            const currentTheme = AppTheme [this.context[0]];
            revenir(
                

    Titre 1

    Ceci est un paragraphe

    );     } }
  2. La version du composant MainWithClass qui utilise la méthode ThemeContext.Consumer :
     import React, {Component} from "react ";
    importer ThemeContext depuis "../Context/ThemeContext";
    importer AppTheme depuis "../Colors";
    
    classe Main étend Component {
        constructeur () {
            super();
            this.state = {}
        }
        render () {
            revenir (
                
                    {
                        ([theme]) => {
                            const currentTheme = AppTheme [theme];
                            revenir(
                                

    Titre 1

    Ceci est un paragraphe

    )                                             }                 }             
            );     } } exporter par défaut Main;

Modification de notre composant MainWithFunction

Le composant MainWithFunction doit être modifié comme suit:

 import React, {useContext} de "react";
importer ThemeContext depuis "../Context/ThemeContext";
importer AppTheme depuis "../Colors";


const Main = () => {
    const theme = useContext (ThemeContext) [0];
    const currentTheme = AppTheme [theme];
    revenir(
        

Titre 1

Ceci est un paragraphe

); } exporter par défaut Main;

Conclusion

Ça y est! Nous avons réussi à implémenter deux modes de thème pour notre application React à l'aide de l'API Context.

Au cours de ce processus, nous avons appris:

  • Qu'est-ce que l'API Context et le problème qu'elle résout;
  • Quand utiliser le contexte API;
  • Créer Contexte et le consommer dans des composants fonctionnels et basés sur des classes.

Lectures complémentaires sur SmashingMag: