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

Pour ce didacticiel, vous devez avoir une bonne compréhension des crochets. Cependant, avant de commencer, je vais brièvement parler de ce que c'est et des crochets que nous utiliserons dans cet article.

Selon 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 crochet React. Il nous permet d'utiliser l'état, les références et d'autres fonctionnalités React dans nos composants fonctionnels.

Laissez-nous discuter des deux crochets que nous rencontrerons dans cet article.

le useState Crochet

Le crochet useState nous permet d'utiliser l'état dans nos composants fonctionnels. UNE useState hook 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 œil à l'exemple suivant:

importer React, {useState} de "react";

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

Ici, compter 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 useContext Crochet

Je vais en discuter plus tard dans l'article, mais ce crochet est essentiellement nous permet de consommer la valeur d'un contexte. Ce que cela signifie réellement deviendra plus évident plus tard dans l'article.

Espaces de travail de fil

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 contextuelle?

Nous voulons créer un composant "bascule 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 thème actuel pour pouvoir être stylé 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 Etat:

importer React à partir de "react";
importer ReactDOM depuis "react-dom";

fonction App () {
  revenir (
    

{thème}

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

{thème}

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

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

Nous allons créer un état appelé "thème" en utilisant le useState crochet. le useState hook 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 App composant. 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 un si , un moyen plus pratique de le faire est à l'aide de l'opérateur ternaire en JavaScript.

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

Alors maintenant, nous avons écrit notre sur clic gestionnaire. Ajoutons cet élément de bouton au App composant:


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


Maintenant, nous devrions avoir ceci:

importer React à partir 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(

{thème}

); } 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 grande, il serait difficile d'utiliser le thème dans des composants profondément imbriqués et le code deviendrait difficile à utiliser.

Présentation de l'API Context

Permettez-moi de vous présenter l'API contextuelle. Selon la documentation 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 permet de mettre des données particulières à la disposition de tous les composants de l'arborescence des composants, quelle que soit la profondeur d'imbrication de ce composant.

Regardons 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 de l'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, ce qui est le Petit enfant composant. le ChildComponent n'avait rien à voir avec les accessoires de thème mais était juste utilisé comme intermédiaire.

Maintenant, imaginez le Petit enfant le composant é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 Le contexte résout. Avec Le contexte, chaque composant de l'arborescence des composants a accès aux données que nous décidons de placer dans notre contexte.

Commençons par Le contexte

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 construire un ThemeToggler composant 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 créer-réagir-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 ton / src dossier. Vous pouvez également créer un dossier appelé /le contexte et placez votre ThemeContext déposer là-dedans si vous voulez.

Passons maintenant.

Création de votre API de contexte

Nous allons créer notre contexte thématique dans notre ThemeContext.js fichier.

Pour créer un contexte, nous utilisons React.createContext qui crée un objet de contexte. Vous pouvez passer 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».

importer React à partir 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 React, chaque objet de contexte est livré 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.

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

Une fois la ThemeContext a été importé, nous devons joindre le contenu de notre App composant dans ThemeContext.Provider balises et donner la ThemeContext.Provider composant 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 / src dossier 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 le AppTheme objet comme ça:

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:

  • Entête
  • ThemeToggler
  • MainWithClass
importer 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 retourner un vide div.)

importer React à partir de "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 nos 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 des composants basés sur une classe:

  1. La première méthode consiste à Class.contextType.

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

    importer 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];
            revenir(
                
    );     } }

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

    Maintenant, nous allons saisir les couleurs du currentTheme variable et les utiliser pour styliser un balisage.

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

    Rubrique 1

    Ceci est un paragraphe

    C'est ça! Cette méthode, cependant, vous limite à ne consommer qu'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 transmise à cette fonction en tant qu'argument.

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

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

    Rubrique 1

    Ceci est un paragraphe

    )                                             }                 }
    );     } }

    Comme vous pouvez le voir, nous avons utilisé la valeur actuelle de notre ThemeContext que nous avons aliasé comme "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 qu'avec des composants basés sur des classes. Pour consommer le contexte dans un composant fonctionnel, nous utiliserons un hook appelé useContext.

Voici ce que consomme notre ThemeContext avec un composant fonctionnel ressemblerait à:

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

Rubrique 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 useContext accrocher avec notre ThemeContext passé 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 ThemeToggler Composant

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

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

Nous avons transmis un tableau au React.createContext une fonction. 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 useState crochet, mais ce n'est pas exactement le résultat d'un useState crochet.

Nous allons maintenant modifier notre App.js fichier. Nous devons changer la valeur transmise au fournisseur en useState crochet. Maintenant, la valeur de notre contexte thématique est useState crochet dont la valeur par défaut est «light».

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

Écrire notre ThemeToggler Composant

Écrivons maintenant notre ThemeToggler composant:

importer 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;

Depuis 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 sur clic gestionnaire d'événements pour notre ThemeToggler. Avec ce code, chaque fois que l'on clique sur le basculeur de thème, il change le thème de notre application.

Nous allons maintenant éditer les différentes versions de notre Principale composant.

Modification de notre MainWithClass Composant

  1. La version du MainWithClass composant qui utilise le Class.contextType méthode:
    importer 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(
                

    Rubrique 1

    Ceci est un paragraphe

    );     } }
  2. La version du MainWithClass composant qui utilise le ThemeContext.Consumer méthode:
    importer React, {Component} de "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(
                                

    Rubrique 1

    Ceci est un paragraphe

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

Modification de notre MainWithFunction Composant

le MainWithFunction Le composant doit être modifié comme suit:

importer 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(
        

Rubrique 1

Ceci est un paragraphe

); } exporter par défaut Main;

Conclusion

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

Ce faisant, nous avons appris:

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

Lectures complémentaires sur SmashingMag:

Smashing Editorial
(dm, il)