Fermer

avril 28, 2020

Le guide complet –


React Router est la bibliothèque de routage standard de facto pour React. Lorsque vous devez naviguer dans une application React avec plusieurs vues, vous aurez besoin d'un routeur pour gérer les URL. React Router s'en charge en gardant l'interface utilisateur de votre application et l'URL synchronisées.

Ce didacticiel vous présente React Router v5 et beaucoup de choses que vous pouvez en faire.

Introduction

React est un bibliothèque populaire pour créer des applications monopages (SPA) qui sont rendues côté client. Un SPA peut avoir plusieurs vues (alias pages ), et contrairement aux applications multipages classiques, la navigation dans ces vues ne devrait pas entraîner le rechargement de la page entière. Au lieu de cela, nous voulons que les vues soient rendues en ligne dans la page actuelle. L'utilisateur final, habitué aux applications multipages, s'attend à ce que les fonctionnalités suivantes soient présentes dans un SPA:

  • Chaque vue d'une application doit avoir une URL qui spécifie cette vue de manière unique. Cela permet à l'utilisateur de mettre l'URL en signet pour référence ultérieurement. Par exemple, www.example.com/products .
  • Le bouton Précédent et Suivant du navigateur devrait fonctionner comme prévu.
  • Les vues imbriquées générées dynamiquement devraient également avoir de préférence leur propre URL. Par exemple, example.com/products/shoes/101 où 101 est l'ID du produit.

Le routage est le processus de synchronisation de l'URL du navigateur avec ce qui est affiché sur la page. . React Router vous permet de gérer le routage de façon déclarative . L'approche de routage déclaratif vous permet de contrôler le flux de données dans votre application, en disant «la route doit ressembler à ceci»:


Vous pouvez placer votre composant où vous voulez que votre route soit rendue. Comme et toutes les autres API de React Router avec lesquelles nous allons traiter ne sont que des composants, vous pouvez facilement vous habituer au routage dans React.

Une note avant de commencer. Il y a une idée fausse commune selon laquelle React Router est une solution de routage officielle développée par Facebook. En réalité, il s'agit d'une bibliothèque tierce largement appréciée pour sa conception et sa simplicité. Si vos besoins se limitent aux routeurs pour la navigation, vous pouvez implémenter un routeur personnalisé à partir de zéro sans trop de tracas. Cependant, comprendre comment les principes de base de React Router vous permettront de mieux comprendre le fonctionnement d'un routeur.

Présentation

Ce didacticiel est divisé en différentes sections. Tout d'abord, nous allons configurer React et React Router à l'aide de npm. Ensuite, nous passerons directement aux principes de base de React Router. Vous trouverez différentes démonstrations de code de React Router en action. Les exemples traités dans ce didacticiel incluent:

  1. routage de navigation de base
  2. routage imbriqué
  3. routage imbriqué avec paramètres de chemin
  4. routage protégé

Tous les concepts liés à la construction de ces itinéraires seront discutés en cours de route. Le code complet du projet est disponible sur ce dépôt GitHub . Une fois que vous êtes dans un répertoire de démonstration particulier, exécutez npm install pour installer les dépendances. Pour servir l'application sur un serveur de développement, exécutez npm start et rendez-vous sur http: // localhost: 3000 / pour voir la démo en action.

Commençons!

Configuration de React Router

Je suppose que vous disposez déjà d'un environnement de développement opérationnel. Sinon, rendez-vous sur « Premiers pas avec React et JSX ». Vous pouvez également utiliser Create React App pour générer les fichiers nécessaires à la création d'un projet React de base. Il s'agit de la structure de répertoires par défaut générée par Create React App:

  react-router-demo
    ├── .gitignore
    ├── package.json
    ├── public
    │ ├── favicon.ico
    │ ├── index.html
    │ └── manifest.json
    ├── README.md
    ├── src
    │ ├── App.css
    │ ├── App.js
    │ ├── App.test.js
    │ ├── index.css
    │ ├── index.js
    │ ├── logo.svg
    │ └── registerServiceWorker.js
    └── yarn.lock

La bibliothèque React Router comprend trois packages: react-router react-router-dom et react-router-native . react-router est le noyau du routeur, tandis que les deux autres sont spécifiques à l'environnement. Vous devez utiliser react-router-dom si vous créez un site Web et react-router-native si vous êtes dans un environnement de développement d'applications mobiles utilisant React Native. [19659021] Utilisez npm pour installer react-router-dom :

 npm install --save react-router-dom

Bases de React Router

Voici un exemple de l'apparence de nos routes:

 / * Composant d'application * /
classe App étend React.Component {
  render () {
    revenir (
      
/ * Les composants d'itinéraire sont rendus si l'accessoire de chemin correspond à l'URL actuelle * /         
);   } }   

Routeur

Vous avez besoin d'un composant de routeur et de plusieurs composants de route pour configurer une route de base comme illustré ci-dessus. Puisque nous créons une application basée sur un navigateur, nous pouvons utiliser deux types de routeurs à partir de l'API React Router:

La principale différence entre eux est évident dans les URL qu'ils créent:

 // 
http://example.com/about

// 
http://example.com/#/about

Le est plus populaire parmi les deux car il utilise l'API HTML5 History pour garder une trace de l'historique de votre routeur. Le d'autre part, utilise la partie de hachage de l'URL ( window.location.hash ) pour se souvenir des choses. Si vous avez l'intention de prendre en charge les navigateurs hérités, vous devez vous en tenir à .

Enveloppez le composant autour du composant App.

index.js

 / * Import statement * /
importer React depuis "react";
importer ReactDOM depuis "react-dom";

/ * L'application est le point d'entrée du code React. * /
importer l'application depuis "./App";

/ * importer BrowserRouter depuis 'react-router-dom' * /
importer {BrowserRouter} depuis "react-router-dom";

ReactDOM.render (
  
    
  ,
  document.getElementById ("root")
);

Remarque: Un composant routeur ne peut avoir qu'un seul élément enfant. L'élément enfant peut être un élément HTML – tel que div – ou un composant react.

Pour que React Router fonctionne, vous devez importer l'API appropriée à partir de react-router-dom bibliothèque. Ici, j'ai importé le BrowserRouter dans index.js . J'ai également importé le composant App de App.js . App.js comme vous l'avez peut-être deviné, est le point d'entrée des composants React.

Le code ci-dessus crée une instance de l'historique pour l'ensemble de notre composant App. Permettez-moi de vous présenter officiellement l'historique.

history

history est une bibliothèque JavaScript qui vous permet de gérer facilement l'historique des sessions partout où JavaScript s'exécute. historique fournit une API minimale qui vous permet de gérer la pile d'historique, de naviguer, de confirmer la navigation et de conserver l'état entre les sessions. – React Training docs

Chaque composant de routeur crée un objet historique qui garde la trace de l'emplacement actuel ( history.location ) ainsi que des emplacements précédents d'une pile. Lorsque l'emplacement actuel change, la vue est restituée et vous obtenez une sensation de navigation. Comment l'emplacement actuel change-t-il? L'objet histoire a des méthodes telles que history.push () et history.replace () pour prendre soin de cela. history.push () est appelé lorsque vous cliquez sur un composant et history.replace () est appelé lorsque vous utilisez . D'autres méthodes – telles que history.goBack () et history.goForward () – sont utilisées pour parcourir la pile d'historique en remontant ou en avançant une page.

, nous avons des liens et des routes.

Liens et routes

Le composant est le composant le plus important du routeur React. Il affiche une certaine interface utilisateur si l'emplacement actuel correspond au chemin de l'itinéraire. Idéalement, un composant devrait avoir un accessoire nommé chemin et si le chemin d'accès correspond à l'emplacement actuel, il est rendu.

Le composant d'autre part, est utilisé pour naviguer entre les pages. Il est comparable à l'élément d'ancrage HTML. Cependant, l'utilisation de liens d'ancrage entraînerait une actualisation du navigateur, ce que nous ne voulons pas. Donc, à la place, nous pouvons utiliser pour naviguer vers une URL particulière et voir la vue restituée sans actualisation du navigateur.

Nous avons couvert tout ce que vous devez savoir pour créer un routeur de base. Créons-en un.

Démo 1: Routage de base

src / App.js

 / * Importer des instructions * /
importer React, {Component} depuis "react";
importer {Link, Route, Switch} depuis "react-router-dom";

/ * Composant domestique * /
const Home = () => (
  

Accueil

); / * Composant de catégorie * / const Catégorie = () => (   

Catégorie

); / * Composant produits * / const Produits = () => (   

Produits

); exporter la fonction par défaut App () {   revenir (     
/ * Les composants d'itinéraire sont rendus si l'accessoire de chemin correspond à l'URL actuelle * /       
); }

Nous avons déclaré les composants pour la maison, la catégorie et les produits dans App.js . Bien que ce soit correct pour le moment, lorsque le composant commence à grossir, il est préférable d'avoir un fichier séparé pour chaque composant. En règle générale, je crée généralement un nouveau fichier pour un composant s'il occupe plus de 10 lignes de code. À partir de la deuxième démo, je vais créer un fichier séparé pour les composants qui sont devenus trop gros pour tenir dans le fichier App.js .

À l'intérieur du composant App, nous avons écrit la logique pour le routage. Le chemin du est mis en correspondance avec l'emplacement actuel et un composant est rendu. Le composant qui doit être rendu est transmis comme deuxième accessoire.

Ici, / correspond à la fois à / et / category . Par conséquent, les deux itinéraires sont mis en correspondance et rendus. Comment éviter cela? Vous devez transmettre les accessoires exact = {true} au routeur avec path = '/' :

 

Si vous voulez qu'un itinéraire soit rendu uniquement si les chemins sont exactement les mêmes, vous devez utiliser les accessoires exacts.

Routage imbriqué

Pour créer des itinéraires imbriqués, nous devons avoir une meilleure compréhension de la façon dont [19659010] fonctionne. Faisons cela.

a trois accessoires que vous pouvez utiliser pour définir ce qui sera rendu:

  • composant . Nous l'avons déjà vu en action. Lorsque l'URL est mise en correspondance, le routeur crée un élément React à partir du composant donné à l'aide de React.createElement .
  • render . C'est pratique pour le rendu en ligne. Le prop de rendu attend une fonction qui renvoie un élément lorsque l'emplacement correspond au chemin de l'itinéraire.
  • enfants . Le prop enfant est similaire au rendu en ce qu'il attend une fonction qui retourne un élément React. Cependant, les enfants sont rendus indépendamment du fait que le chemin correspond à l'emplacement ou non.

Chemin et correspondance

Le chemin est utilisé pour identifier la partie de l'URL que le routeur doit faire correspondre. Il utilise la bibliothèque Path-to-RegExp pour transformer une chaîne de chemin d'accès en une expression régulière. Il sera ensuite comparé à l'emplacement actuel.

Si le chemin du routeur et l'emplacement sont correctement mis en correspondance, un objet est créé et nous l'appelons l'objet match . L'objet match contient plus d'informations sur l'URL et le chemin d'accès. Ces informations sont accessibles via ses propriétés, répertoriées ci-dessous:

  • match.url . Une chaîne qui renvoie la partie correspondante de l'URL. Ceci est particulièrement utile pour la construction de chemins de correspondance imbriqués
  • . Une chaîne qui renvoie la chaîne de chemin d'accès de l'itinéraire, c'est-à-dire . Nous allons l'utiliser pour créer des imbriqués s.
  • match.isExact . Un booléen qui renvoie true si la correspondance était exacte (sans aucun caractère de fin).
  • match.params . Un objet contenant des paires clé / valeur de l'URL analysées par le package Path-to-RegExp.

Maintenant que nous savons tout sur s, construisons un routeur avec des routes imbriquées.

Switch Component

Avant de nous diriger vers le code de démonstration, je veux vous présenter le composant . Lorsque plusieurs s sont utilisés ensemble, tous les itinéraires qui correspondent sont rendus inclusivement. Considérez ce code de la démo 1. J'ai ajouté une nouvelle route pour montrer pourquoi est utile:

 


 (

Je veux que ce texte apparaisse pour toutes les routes autres que '/', '/ products' et '/ category'

)} />

Si l'URL est / products tous les itinéraires correspondant à l'emplacement / products sont rendus. Ainsi, le avec chemin : id est rendu avec le composant Produits . C'est par conception. Cependant, si ce n'est pas le comportement que vous attendez, vous devez ajouter le composant à vos itinéraires. Avec seul le premier enfant correspondant à l'emplacement est rendu.

Démo 2: routage imbriqué

Plus tôt, nous avons créé des itinéraires pour / / category et / products . Et si nous voulions une URL de la forme / category / shoes ?

src / App.js

 import React, {Component} de "react";
importer {Link, Route, Switch} depuis "react-router-dom";
importer la catégorie de "./Category";

exporter la fonction par défaut App () {
  revenir (
    
); } / * Code pour le composant Home and Products omis pour des raisons de concision * /

Contrairement à la version précédente de React Router, dans la version 4 et les suivantes, les imbriqués devraient de préférence aller à l'intérieur du composant parent. Autrement dit, le composant Catégorie est le parent ici, et nous déclarerons les itinéraires pour catégorie /: nom à l'intérieur du composant parent.

src / Category.jsx

 import React from " réagir";
importer {Link, Route} depuis "react-router-dom";

const Category = ({match}) => {
  revenir (
    
      {""}       
  • Chaussures
  • Bottes
  • Chaussures
(           
            {""}             

{match.params.name}

)}       />     
  ); }; exporter la catégorie par défaut;

Premièrement, nous avons déclaré quelques liens pour les itinéraires imbriqués. Comme mentionné précédemment, match.url sera utilisé pour créer des liens imbriqués et match.path pour les itinéraires imbriqués. Si vous ne parvenez pas à comprendre le concept de correspondance, console.log (match) fournit des informations utiles qui pourraient aider à le clarifier.

  (
    

{match.params.name}

)} />

Il s'agit de notre première tentative de routage dynamique. Au lieu de coder en dur les itinéraires, nous avons utilisé une variable dans le chemin d'accès. : nom est un paramètre de chemin et capture tout après catégorie / jusqu'à ce qu'une autre barre oblique soit rencontrée. Ainsi, un chemin d'accès comme produits / chaussures de course créera un objet params comme suit:

 {
  nom: "chaussures de course";
}

Les données capturées doivent être accessibles sur match.params ou props.match.params selon la façon dont les accessoires sont passés. L'autre chose intéressante est que nous avons utilisé un accessoire de rendu . Les accessoires de rendu sont assez pratiques pour les fonctions en ligne qui ne nécessitent pas de composant propre.

Démo 3: routage imbriqué avec les paramètres de chemin

Compliquons les choses un peu plus, n'est-ce pas? Un routeur du monde réel devra traiter les données et les afficher dynamiquement. Supposons que les données produit soient renvoyées par une API serveur du formulaire ci-dessous.

src / Products.jsx

 const productData = [
  {
    id: 1,
    name: "NIKE Liteforce Blue Sneakers",
    description:
      "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin molestie.",
    status: "Available",
  },
  {
    id: 2,
    name: "Stylised Flip Flops and Slippers",
    description:
      "Mauris finibus, massa eu tempor volutpat, magna dolor euismod dolor.",
    status: "Out of Stock",
  },
  {
    id: 3,
    name: "ADIDAS Adispree Running Shoes",
    description:
      "Maecenas condimentum porttitor auctor. Maecenas viverra fringilla felis, eu pretium.",
    status: "Available",
  },
  {
    id: 4,
    name: "ADIDAS Mid Sneakers",
    description:
      "Ut hendrerit venenatis lacus, vel lacinia ipsum fermentum vel. Cras.",
    status: "Out of Stock",
  },
];

Nous devons créer des itinéraires pour les chemins suivants:

  • / products . Cela devrait afficher une liste de produits.
  • / products /: productId . Si un produit avec le : productId existe, il doit afficher les données du produit et sinon, il doit afficher un message d'erreur.

src / Products.jsx

 / * Les instructions d'importation ont été laissé de côté pour la brièveté du code * /

const Products = ({match}) => {
  const productsData = [
    {
      id: 1,
      name: "NIKE Liteforce Blue Sneakers",
      description:
        "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin molestie.",
      status: "Available",
    },

    //Rest of the data has been left out for code brevity
  ];
  / * Créez un tableau d'articles `
  • ` pour chaque produit * /   const linkList = productsData.map ((product) => {     revenir (       
  • {product.name}
  • );   });   revenir (     

    Produits

      {linkList}
    }       />       
    Veuillez sélectionner un produit.
    }       />     
      ); };

    Premièrement, nous avons créé une liste de en utilisant les productsData.id s et l'avons stockée dans linkList . L'itinéraire prend un paramètre dans la chaîne de chemin d'accès qui correspond à celui de l'ID de produit.

      }
    />
    

    Vous vous attendiez peut-être à component = {Product} au lieu de la fonction de rendu en ligne. Le problème est que nous devons transmettre productsData au composant Product avec tous les accessoires existants. Bien qu'il existe d'autres façons de procéder, je trouve que cette méthode est la plus simple. {... props} utilise la syntaxe étalée d'ES6 pour transmettre l'intégralité de l'objet props au composant.

    Voici le code du composant Product.

    src / Product.jsx

     / * Les instructions d'importation ont été omises pour des raisons de brièveté du code * /
    
    const Product = ({match, data}) => {
      var product = data.find (p => p.id == match.params.productId);
      var productData;
    
      si (produit)
        productData = (
          

    {product.name}

    {product.description}


    {product.status}

    {""}       
        );   else productData =

    Désolé. Le produit n'existe pas

    ;   revenir (     
    {productData}
    ); };

    La méthode find est utilisée pour rechercher dans le tableau un objet avec une propriété ID égale à match.params.productId . Si le produit existe, le productData s'affiche. Sinon, un message "Le produit n'existe pas" s'affiche.

    Protection des itinéraires

    Pour la démo finale, nous allons discuter des techniques de protection des itinéraires. Donc, si quelqu'un essaie d'accéder à / admin il devra d'abord se connecter. Cependant, il y a certaines choses que nous devons couvrir avant de pouvoir protéger les routes.

    Redirection

    Comme les redirections côté serveur, remplacera l'emplacement actuel dans la pile d'historique par un nouvel emplacement. Le nouvel emplacement est spécifié par le prop à . Voici comment nous allons utiliser :

     <Rediriger vers = {{chemin d'accès: '/ login', indiquer: {from: props.location}}}
    

    Donc, si quelqu'un essaie d'accéder à / admin alors qu'il est déconnecté, il sera redirigé vers la route / login . Les informations sur l'emplacement actuel sont transmises via l'état, de sorte que si l'authentification réussit, l'utilisateur peut être redirigé vers l'emplacement d'origine. Dans le composant enfant, vous pouvez accéder à ces informations dans this.props.location.state .

    Itinéraires personnalisés

    Un itinéraire personnalisé est un mot de fantaisie pour un itinéraire imbriqué dans un composant. Si nous devons décider si un itinéraire doit être rendu ou non, l'écriture d'un itinéraire personnalisé est la voie à suivre. Voici l'itinéraire personnalisé déclaré parmi d'autres itinéraires.

    src / App.js

     / * Ajoutez le composant PrivateRoute aux itinéraires existants * /
    
    
    
      
      
      
      
      
    
    

    fakeAuth.isAuthenticated renvoie true si l'utilisateur est connecté et false dans le cas contraire.

    Voici la définition de PrivateRoute:

    src / App.js

     / * Définition du composant PrivateRoute * /
    const PrivateRoute = ({composant: Composant, ... reste}) => {
      revenir (
        
            fakeAuth.isAuthenticated === true? (
              
            ): (
              
            )
          }
        />
      );
    };
    

    La route affiche le composant Admin si l'utilisateur est connecté. Sinon, l'utilisateur est redirigé vers / login . La bonne chose à propos de cette approche est qu'elle est évidemment plus déclarative et que PrivateRoute est réutilisable.

    Enfin, voici le code du composant Login:

    src / Login.jsx

     import React , {useState} de "react";
    importer {Redirect} depuis "react-router-dom";
    
    exporter la fonction par défaut Login (accessoires) {
      const {from} = props.location.state || {from: {pathname: "/"}};
      console.log (de);
      const [redirectToReferrer, setRedirectToReferrer] = useState (false);
    
      const login = () => {
        fakeAuth.authenticate (() => {
          setRedirectToReferrer (true);
        });
      };
    
      if (redirectToReferrer) {
        retour ;
      }
    
      revenir (
        

    Vous devez vous connecter pour afficher la page à {from.pathname}

    ); } / * Une fausse fonction d'authentification * / export const fakeAuth = {   isAuthenticated: false,   authentifier (cb) {     this.isAuthenticated = true;     setTimeout (cb, 100);   } };

    La ligne ci-dessous illustre la déstructuration d'objet qui fait partie de la spécification ES6:

     const {from} = this.props.location.state || {from: {pathname: "/"}};
    

    Assemblons les pièces du puzzle, d'accord? Voici la démonstration finale de l'application que nous avons créée à l'aide du routeur React.

    Démo 4: Protection des itinéraires

    Résumé

    Comme vous l'avez vu dans cet article, React Router est une bibliothèque puissante qui complète React pour construire de meilleures routes déclaratives. Contrairement aux versions précédentes de React Router, en v5, tout n'est que «des composants». De plus, le nouveau modèle de conception s'intègre parfaitement dans la façon de faire de React.

    Dans ce didacticiel, nous avons appris:

    • comment configurer et installer React Router
    • les bases du routage et certains composants essentiels tels que [19659202] et
    • comment créer un routeur minimal pour la navigation et les routes imbriquées
    • comment construire des routes dynamiques avec des paramètres de chemin

    Enfin, nous avons appris quelques techniques avancées de routage pour créer la finale démo pour les itinéraires protégés.




    Source link