One place for hosting & domains

      Comment ajouter les tests unitaires à votre projet Django


      L’auteur a choisi le Open Internet/Free Speech Fund pour recevoir un don dans le cadre du programme Write for Donations.

      Introduction

      Il est presque impossible de construire des sites web qui fonctionnent parfaitement du premier coup sans erreurs. C’est pourquoi vous devez tester votre application web pour trouver ces erreurs et y remédier de manière proactive. Afin d’améliorer l’efficacité des tests, il est courant de décomposer les tests en unités qui testent des fonctionnalités spécifiques de l’application web. Cette pratique est appelée les tests unitaires.   Il est plus facile de détecter les erreurs, car les tests se concentrent sur de petites parties (unités) de votre projet indépendamment des autres parties.

      Tester un site web peut être une tâche complexe à entreprendre car il est constitué de plusieurs couches de logique comme le traitement des requêtes HTTP, la validation des formulaires et les modèles de rendu. Cependant, Django fournit un ensemble d’outils qui permettent de tester votre application web en toute transparence.   Dans Django, la façon préférée d’écrire des tests est d’utiliser le module Python unittest, bien qu’il soit possible d’utiliser d’autres cadres de test. 

      Dans ce tutoriel, vous allez mettre en place une suite de tests dans votre projet Django et écrire des tests unitaires pour les modèles et les vues de votre application. Vous effectuerez ces tests, analyserez leurs résultats et apprendrez comment trouver les causes des échecs.

      Conditions préalables

      Avant de commencer ce tutoriel, vous aurez besoin des éléments suivants :

      Étape 1 – Ajouter une séquence de tests à votre demande Django

      Une séquence de tests dans Django est une collection de tous les scénarios de test de toutes les applications de votre projet. Pour permettre à l’utilitaire de test de Django de découvrir les scénarios de test que vous avez, vous écrivez les scénarios de test dans des scripts dont le nom commence par test.   Au cours de cette étape, vous allez créer la structure des répertoires et des fichiers de votre séquence de tests, et y créer un scénario de test vide.

      Si vous avez suivi la série de tutoriels Django Development, vous aurez une application Django appelée blogsite.

      Créons un dossier pour contenir tous nos scripts de test. Tout d’abord, activez l’environnement virtuel :

      • cd ~/my_blog_app
      • . env/bin/activate

      Ensuite, naviguez vers le répertoire appblogsite, le dossier qui contient les fichiers models.py et views.py, puis créez un nouveau dossier appelé tests :

      • cd ~/my_blog_app/blog/blogsite
      • mkdir tests

      Ensuite, vous transformerez ce dossier en un paquet Python, ajoutez donc un fichier __init__.py :

      • cd ~/my_blog_app/blog/blogsite/tests
      • touch __init__.py

      Vous allez maintenant ajouter un fichier pour tester vos modèles et un autre pour tester vos vues :

      • touch test_models.py
      • touch test_views.py

      Enfin, vous allez créer un scénario de test vide dans test_models.py. Vous devrez importer la classe Django TestCase et en faire une super classe de votre propre classe de test case. Plus tard, vous ajouterez des méthodes à ce scénario de test pour tester la logique de vos modèles. Ouvrez le fichier test_models.py :

      Ajoutez maintenant le code suivant au fichier :

      ~/my_blog_app/blog/blogsite/tests/test_models.py

      from django.test import TestCase
      
      class ModelsTestCase(TestCase):
          pass
      

      Vous avez maintenant ajouté avec succès une séquence de tests à l’appli blogsite. Ensuite, vous remplirez les détails du modèle de cas test vide que vous avez créé ici.

      Étape 2 – Tester votre code Python

      Dans cette étape, vous allez tester la logique du code écrit dans le fichier models.py. En particulier, vous testerez la méthode de sauvegarde du modèle Post afin de vous assurer qu’il crée la bonne portion du titre d’un message lorsqu’il est appelé. 

      Commençons par regarder le code que vous avez déjà dans votre fichier models.py pour la méthode de sauvegarde du modèle Post :

      • cd ~/my_blog_app/blog/blogsite
      • nano models.py

      Vous verrez ce qui suit :

      ~/my_blog_app/blog/blogsite/models.py

      class Post(models.Model):
          ...
          def save(self, *args, **kwargs):
              if not self.slug:
                  self.slug = slugify(self.title)
              super(Post, self).save(*args, **kwargs)
          ...
      

      On peut voir qu’il vérifie si le message sur le point d’être sauvegardé a une valeur de slug, et si ce n’est pas le cas, il appelle slugify pour lui créer une valeur de slug. C’est le type de logique que vous pourriez vouloir tester pour vous assurer que les slugs sont effectivement créés lors de la sauvegarde d’un message.

      Fermez le dossier.

      Pour le tester, retournez à test_models.py :

      Mettez-le ensuite à jour en ajoutant les parties surlignées :

      ~/my_blog_app/blog/blogsite/tests/test_models.py

      from django.test import TestCase
      from django.template.defaultfilters import slugify
      from blogsite.models import Post
      
      
      class ModelsTestCase(TestCase):
          def test_post_has_slug(self):
              """Posts are given slugs correctly when saving"""
              post = Post.objects.create(title="My first post")
      
              post.author = "John Doe"
              post.save()
              self.assertEqual(post.slug, slugify(post.title))
      

      Cette nouvelle méthode test_post_has_slug crée un nouvel article avec le titre « My first post », puis donne à l’article un auteur et l’enregistre. Ensuite, à l’aide de la méthode assertEqual du module Python unittest, il vérifie si le slug du message est correct. La méthode assertEqual vérifie si les deux arguments qui lui sont transmis sont égaux tels que déterminés par l’opérateur « == » et signale une erreur s’ils ne le sont pas.

      Sauvegarder et quitter test_models.py.

      Voici un exemple de ce qui peut être testé. Plus vous ajoutez de logique à votre projet, plus il y a de choses à tester. Si vous ajoutez plus de logique à la méthode de sauvegarde ou créez de nouvelles méthodes pour le modèle Post, vous voudriez ajouter plus de tests ici. Vous pouvez les ajouter à la méthode test_post_has_slug ou créer de nouvelles méthodes de test, mais leurs noms doivent commencer par test.

      Vous avez créé avec succès un cas test pour le modèle Post où vous avez affirmé que les slugs sont correctement créés après la sauvegarde. Dans l’étape suivante, vous rédigerez un scénario de test pour tester les vues.

      Étape 3 – Utiliser le client test de Django

      Dans cette étape, vous allez écrire un scénario de test qui teste une vue en utilisant le client de test Django. Le test client est une classe Python qui agit comme un navigateur web factice, vous permettant de tester vos vues et d’interagir avec votre application Django de la même manière qu’un utilisateur le ferait. Vous pouvez accéder au client test en vous référant à self.client dans vos méthodes de test. Par exemple, créons un cas test dans test_views.py Tout d’abord, ouvrez le fichier test_views.py :

      Ajoutez ensuite ce qui suit :

      ~/my_blog_app/blog/blogsite/tests/test_views.py

      from django.test import TestCase
      
      
      class ViewsTestCase(TestCase):
          def test_index_loads_properly(self):
              """The index page loads properly"""
              response = self.client.get('your_server_ip:8000')
              self.assertEqual(response.status_code, 200)
      

      Le ViewsTestCase contient une méthode test_index_loads_properly qui utilise le client de test Django pour visiter la page d’index du site (http://your_server_ip:8000, où your_server_ip est l’adresse IP du serveur que vous utilisez). Ensuite, la méthode de test vérifie si la réponse a un code de statut de 200, ce qui signifie que la page a répondu sans aucune erreur. Vous pouvez donc être sûr que lorsque l’utilisateur se rendra sur le site, il répondra lui aussi sans erreur.

      Outre le code de statut, vous pouvez lire d’autres propriétés de la réponse du client de test que vous pouvez tester dans la page des réponses de test de la documentation de Django.

      Au cours de cette étape, vous avez créé un scénario de test pour vérifier que la vue rendant la page d’index fonctionne sans erreur. Il y a maintenant deux scénarios de test dans votre séquence de tests. Au cours de l’étape suivante, vous les exécuterez pour voir leurs résultats.

      Étape 4 – Effectuer vos tests

      Maintenant que vous avez terminé la construction d’une séquence de tests pour le projet, il est temps d’exécuter ces tests et de voir leurs résultats. Pour effectuer les tests, naviguez dans le dossier blog (contenant le fichier manage.py de l’application) :

      Puis, exécutez-les :

      Vous verrez un résultat similaire à ce qui suit dans votre terminal :

      Output

      Creating test database for alias 'default'... System check identified no issues (0 silenced). .. ---------------------------------------------------------------------- Ran 2 tests in 0.007s OK Destroying test database for alias 'default'...

      Dans cette sortie, il y a deux points .., dont chacun représente un cas de test réussi. Vous allez maintenant modifier test_views.py pour déclencher un test d’échec. Ouvrez le fichier avec :

      Ensuite, changez le code en surbrillance pour :

      ~/my_blog_app/blog/blogsite/tests/test_views.py

      from django.test import TestCase
      
      
      class ViewsTestCase(TestCase):
          def test_index_loads_properly(self):
              """The index page loads properly"""
              response = self.client.get('your_server_ip:8000')
              self.assertEqual(response.status_code, 404)
      

      Ici, vous avez changé le code de statut de 200 à 404. Maintenant, refaites le test à partir de votre répertoire avec manage.py :

      Vous verrez la sortie suivante :

      Output

      Creating test database for alias 'default'... System check identified no issues (0 silenced). .F ====================================================================== FAIL: test_index_loads_properly (blogsite.tests.test_views.ViewsTestCase) The index page loads properly ---------------------------------------------------------------------- Traceback (most recent call last): File "~/my_blog_app/blog/blogsite/tests/test_views.py", line 8, in test_index_loads_properly self.assertEqual(response.status_code, 404) AssertionError: 200 != 404 ---------------------------------------------------------------------- Ran 2 tests in 0.007s FAILED (failures=1) Destroying test database for alias 'default'...

      Vous voyez qu’il y a un message d’échec descriptif qui vous indique le script, le cas de test et la méthode qui a échoué. Il vous indique également la cause de l’échec, le code de statut n’étant pas égal à 404 dans ce cas, avec le message AssertionError: 200 !  404. L’AssertionError est ici soulevée à la ligne de code surlignée dans le fichier test_views.py :

      ~/my_blog_app/blog/blogsite/tests/test_views.py

      from django.test import TestCase
      
      
      class ViewsTestCase(TestCase):
          def test_index_loads_properly(self):
              """The index page loads properly"""
              response = self.client.get('your_server_ip:8000')
              self.assertEqual(response.status_code, 404)
      

      Il vous indique que l’affirmation est fausse, c’est-à-dire que le code de statut de réponse (200) n’est pas ce à quoi on s’attendait (404). Précédant le message d’échec, vous pouvez voir que les deux points .. sont maintenant passés à . F, qui vous indique que le premier cas test a réussi alors que le second ne l’a pas fait.

      Conclusion

      Dans ce tutoriel, vous avez créé une suite de tests dans votre projet Django, ajouté des scénarios de test au modèle de test et à la logique de visualisation, appris comment exécuter des tests et analysé les résultats des tests. Dans un deuxième temps, vous pouvez créer de nouveaux scripts de test pour le code Python qui n’est pas dansmodels.py et views.py.

      Voici quelques articles qui peuvent s’avérer utiles pour créer et tester des sites web avec Django :

      Vous pouvez également consulter notre page thématique sur Django pour d’autres tutoriels et projets.



      Source link

      Comment personnaliser les composants de React avec des props


      L’auteur a choisi Creative Commons​​​ pour recevoir un don dans le cadre du programme Write for DOnations.

      Introduction

      Dans ce tutoriel, vous allez créer des composants personnalisés en passant des props à votre composant. Les props sont des arguments que vous fournissez à un élément JSX. Ils ressemblent à des props HTML standard, mais ils ne sont pas prédéfinis et peuvent avoir de nombreux types de données JavaScript différents, notamment des nombres, des chaînes de caractères, des fonctions, des tableaux et même d’autres composants React. Vos composants personnalisés peuvent utiliser des props pour afficher des données ou utiliser les données pour rendre les composants interactifs. Les props sont un élément clé de la création de composants adaptables à différentes situations, et en apprendre davantage à leur sujet vous donnera les outils nécessaires pour développer des composants personnalisés pouvant gérer des situations uniques.

      Après avoir ajouté des props à votre composant, vous utiliserez les PropTypes pour définir le type de données qu’un composant doit recevoir. Les PropTypes sont un système de type simple permettant de vérifier que les données correspondent aux types attendus pendant l’exécution. Ils servent à la fois de documentation et de vérificateur d’erreurs qui vous aideront à maintenir la prévisibilité de votre demande au fur et à mesure de son évolution.

      À la fin du tutoriel, vous saurez utiliser une variété de props pour construire une petite application qui prendra un ensemble de données sur les animaux et en affichera les informations (nom, nom scientifique, taille, régime alimentaire et informations supplémentaires).

      Note : La première étape consiste à mettre en place un projet vierge sur lequel vous allez construire l’exercice du tutoriel. Si vous avez déjà un projet de travail et que vous souhaitez directement travailler avec des props, commencez par l’étape 2.

      Conditions préalables

      Étape 1 – Créer un projet vide

      Dans cette étape, vous allez créer un nouveau projet en utilisant Create React App. Ensuite, vous supprimerez le projet type et les fichiers connexes qui sont installés lorsque vous démarrez le projet. Enfin, vous créerez une structure de fichiers simple pour organiser vos éléments.

      Pour commencer, faites un nouveau projet. Dans votre ligne de commande, exécutez le script suivant pour installer un nouveau projet en utilisant create-react-app :

      • npx create-react-app prop-tutorial

      Une fois le projet terminé, passez dans le répertoire :

      Dans un nouvel onglet ou une nouvelle fenêtre du terminal, démarrez le projet en utilisant le script de démarrage de l’application Create React. Le navigateur se réactualise automatiquement en fonction des changements, alors laissez ce script fonctionner pendant toute la durée de votre travail :

      Vous obtiendrez un serveur local en fonctionnement. Si le projet ne s’est pas ouvert dans une fenêtre de navigateur, vous pouvez l’ouvrir en naviguant vers http://localhost:3000/. Si vous l’exécutez à partir d’un serveur distant, l’adresse serahttp://your_domain:3000.

      Votre navigateur se chargera avec une simple application React incluse dans le cadre de Create React App :

      Modèle de projet React

      Vous allez construire un tout nouvel ensemble de composants personnalisés. Vous commencerez par effacer un code passe-partout afin de pouvoir avoir un projet vide.

      Pour commencer, ouvrez src/App.js dans un éditeur de texte. C’est le composant root (racine) qui est injecté dans la page. Tous les composants partiront de là. Vous pouvez trouver plus d’informations sur les App.js à Comment mettre en place un projet React avec Create React App.

      Ouvrez src/App.js avec la commande suivante :

      Vous verrez un fichier comme ceci :

      prop-tutorial/src/App.js

      import React from 'react';
      import logo from './logo.svg';
      import './App.css';
      
      function App() {
        return (
          <div className="App">
            <header className="App-header">
              <img src={logo} className="App-logo" alt="logo" />
              <p>
                Edit <code>src/App.js</code> and save to reload.
              </p>
              <a
                className="App-link"
                href="https://reactjs.org"
                target="_blank"
                rel="noopener noreferrer"
              >
                Learn React
              </a>
            </header>
          </div>
        );
      }
      
      export default App;
      

      Supprimez le logo d'importation de ligne de '/logo.svg';   Remplacez ensuite tout ce qui figure dans la déclaration de retour pour renvoyer un ensemble de balises vides : <></>. Vous obtiendrez ainsi une page de validation qui ne renvoie rien. Le code final ressemblera à ceci :

      prop-tutorial/src/App.js

      
      import React from 'react';
      import './App.css';
      
      function App() {
        return <></>;
      }
      
      export default App;
      

      Sauvegardez et quittez l’éditeur de texte.

      Enfin, supprimez le logo. Vous ne l’utiliserez pas dans votre demande et vous devez supprimer les fichiers inutilisés au fur et à mesure de votre travail. Cela vous évitera toute confusion à l’avenir.

      Dans la fenêtre du terminal, tapez la commande suivante :

      Si vous regardez votre navigateur, vous verrez un écran vide.

      écran vierge dans chrome

      Maintenant que vous avez éliminé l’exemple de projet Create React App, créez une structure de fichiers simple. Cela vous aidera à maintenir l’isolement et l’indépendance de vos composants.

      Créez un répertoire appelé components dans le répertoire src. Celui-ci contiendra tous vos composants personnalisés.

      Chaque composant aura son propre répertoire pour stocker le fichier du composant ainsi que les styles, les images s’il y en a, et les tests.

      Créez un répertoire pour App : 

      Déplacez tous les fichiers App dans ce répertoire. Utilisez le joker, *, pour sélectionner tous les fichiers qui commencent par App. quelle que soit leur extension. Utilisez ensuite la commande mv pour les placer dans le nouveau répertoire.

      • mv src/App.* src/components/App

      Enfin, mettez à jour le chemin d’importation relatif dans index.js, qui est le composant root qui amorce l’ensemble du processus.

      La déclaration d’importation doit pointer vers le fichier App.js dans le répertoire App, donc faites la modification suivante en surbrillance :

      prop-tutorial/src/index.js

      import React from 'react';
      import ReactDOM from 'react-dom';
      import './index.css';
      import App from './components/App/App';
      import * as serviceWorker from './serviceWorker';
      
      ReactDOM.render(
        <React.StrictMode>
          <App />
        </React.StrictMode>,
        document.getElementById('root')
      );
      
      // If you want your app to work offline and load faster, you can change
      // unregister() to register() below. Note this comes with some pitfalls.
      // Learn more about service workers: https://bit.ly/CRA-PWA
      serviceWorker.unregister();
      

      Enregistrez et quittez le fichier.

      Maintenant que le projet est mis en place, vous pouvez créer votre premier composant.

      Étape 2 – Construire des composants dynamiques avec des props

      Au cours de cette étape, vous créerez un composant qui changera en fonction des informations saisies, appelées props. Les props sont les arguments que vous passez à une fonction ou à une classe, mais comme vos composants sont transformés en objets de type HTML avec JSX, vous passerez les props comme s’il s’agissait d’attributs HTML. Contrairement aux éléments HTML, vous pouvez transmettre de nombreux types de données différents, des chaînes de caractères, des tables, des objets et même des fonctions.

      Ici, vous allez créer un composant qui affichera des informations sur les animaux. Ce composant prendra le nom et le nom scientifique de l’animal en tant que chaînes, la taille en tant que nombre entier, le régime alimentaire en tant que tableau de chaînes et des informations supplémentaires en tant qu’objet. Vous transmettrez les informations au nouveau composant en tant que props et consommerez ces informations dans votre composant.

      À la fin de cette étape, vous aurez un composant personnalisé qui consommera différents props. Vous pourrez également réutiliser le composant pour afficher un ensemble de données à l’aide d’un composant commun.

      Ajout de données

      Tout d’abord, vous avez besoin de quelques échantillons de données. Créez un fichier dans le répertoire src/App appelé data.

      • touch src/components/App/data.js

      Ouvrez le nouveau fichier dans votre éditeur de texte :

      • nano src/components/App/data.js

      Ensuite, ajoutez un tableau d’objets que vous utiliserez comme échantillon de données :

      prop-tutorial/src/components/App/data.js

      export default [
        {
          name: 'Lion',
          scientificName: 'Panthero leo',
          size: 140,
          diet: ['meat'],
        },
        {
          name: 'Gorilla',
          scientificName: 'Gorilla beringei',
          size: 205,
          diet: ['plants', 'insects'],
          additional: {
            notes: 'This is the eastern gorilla. There is also a western gorilla that is a different species.'
          }
        },
        {
          name: 'Zebra',
          scientificName: 'Equus quagga',
          size: 322,
          diet: ['plants'],
          additional: {
            notes: 'There are three different species of zebra.',
            link: 'https://en.wikipedia.org/wiki/Zebra'
          }
        }
      ]
      

      L’ensemble des objets contient une variété de données et vous donnera l’occasion d’essayer divers props. Chaque objet est un animal séparé avec le nom de l’animal, le nom scientifique, la taille, le régime alimentaire et un champ optionnel appelé additional, qui contiendra des liens ou des notes. Dans ce code, vous avez également exporté le tableau par défaut.

      Enregistrez et quittez le fichier.

      Créer des composants

      Ensuite, créez un composant placeholder appelé AnimalCard. Ce composant prendra éventuellement des props et affichera les données.

      Tout d’abord, créez un répertoire dans src/components appelé AnimalCard puis touchez un fichier appelé src/components/AnimalCard/AnimalCard.js et un fichier CSS appelé src/components/AnimalCard/AnimalCard.css.

      • mkdir src/components/AnimalCard
      • touch src/components/AnimalCard/AnimalCard.js
      • touch src/components/AnimalCard/AnimalCard.css

      Ouvrez AnimalCard.js dans votre éditeur de texte :

      • nano src/components/AnimalCard/AnimalCard.js

      Ajoutez un composant de base qui importe le CSS et renvoie une balise <h2>.

      prop-tutorial/src/components/AnimalCard/AnimalCard.js

      import React from 'react';
      import './AnimalCard.css'
      
      export default function AnimalCard() {
        return <h2>Animal</h2>
      }
      

      Enregistrez et quittez le fichier. Vous devez maintenant importer les données et le composant dans votre composant App de base.

      Ouvrez src/composants/App/App.js :

      • nano src/components/App/App.js

      Importez les données et le composant, puis bouclez les données en retournant le composant pour chaque élément du tableau :

      prop-tutorial/src/components/App/App.js

      import React from 'react';
      import data from './data';
      import AnimalCard from '../AnimalCard/AnimalCard';
      import './App.css';
      
      function App() {
        return (
          <div className="wrapper">
            <h1>Animals</h1>
            {data.map(animal => (
              <AnimalCard key={animal.name}/>
            ))}
          </div>
        )
      }
      
      export default App;
      

      Enregistrez et quittez le fichier. Ici, vous utilisez la méthode du tableau .map() pour itérer sur les données. En plus d’ajouter cette boucle, vous disposez également d’un diviseur d’enveloppe avec une classe que vous utiliserez pour le style et une balise <h1> pour étiqueter votre projet.

      Lorsque vous enregistrez, le navigateur se rechargera et vous verrez une étiquette pour chaque carte.

      Réagissez au projet dans le navigateur sans style

      Ensuite, ajoutez un peu de style pour aligner les articles. Ouvrez App.css :

      • nano src/components/App/App.css

      Remplacez le contenu par ce qui suit pour organiser les éléments :

      prop-tutorial/src/components/App/App.css

      .wrapper {
          display: flex;
          flex-wrap: wrap;
          justify-content: space-between;
          padding: 20px;
      }
      
      .wrapper h1 {
          text-align: center;
          width: 100%;
      }
      

      Ce système utilisera la flexbox pour réorganiser les données afin qu’elles s’alignent. Le padding donne de l’espace dans la fenêtre du navigateur. justify-content répartira l’espace supplémentaire entre les éléments, et .wrapper h1 donnera au label Animal toute la largeur.

      Enregistrez et quittez le fichier. Lorsque vous le ferez, le navigateur se rafraîchira et vous verrez certaines données espacées.

      Projet React dans le navigateur avec des données espacées

      Ajouter des props

      Maintenant que vous avez mis en place vos composants, vous pouvez ajouter votre premier prop. Lorsque vous avez bouclé vos données, vous avez eu accès à chaque objet du tableau de données et aux éléments qu’il contenait. Vous ajouterez chaque élément des données à un prop distinct que vous utiliserez ensuite dans votre composant AnimalCard.

      Ouvrez App.js: 

      • nano src/components/App/App.js

      Ajoutez un prop name à AnimalCard.

      prop-tutorial/src/components/App/App.js

      import React from 'react';
      ...
      function App() {
        return (
          <div className="wrapper">
            <h1>Animals</h1>
            {data.map(animal => (
              <AnimalCard
                key={animal.name}
                name={animal.name}
              />
            ))}
          </div>
        )
      }
      
      export default App;
      

      Enregistrez et quittez le fichier. Le prop name ressemble à un attribut HTML standard, mais au lieu d’une chaîne, vous passerez la propriété name de l’objet animal en accolades.

      Maintenant que vous avez passé un prop à la nouvelle composante, vous devez l’utiliser. Ouvrez le site AnimalCard.js :

      • nano src/components/AnimalCard/AnimalCard.js

      Tous les props que vous passez dans le composant sont rassemblés dans un objet qui sera le premier argument de votre fonction. Déstructurez l’objet pour en retirer des props individuels :

      prop-tutorial/src/components/AnimalCard/AnimalCard.js

      
      import React from 'react';
      import './AnimalCard.css'
      
      export default function AnimalCard(props) {
        const { name } = props;
        return (
          <h2>{name}</h2>
        );
      }
      

      Notez que vous n’avez pas besoin de déstructurer un prop pour l’utiliser, mais que c’est une méthode utile pour traiter les données types de ce tutoriel.

      Après avoir déstructuré l’objet, vous pouvez utiliser les données individuelles. Dans ce cas, vous utiliserez le titre dans une balise <h2>, entourant la valeur d’accolades pour que React sache l’évaluer en JavaScript.

      Vous pouvez également utiliser une propriété sur l’objet prop en utilisant la notation par points. Par exemple, vous pourriez créer un élément <h2> comme celui-ci : <h2>{props.title}</h2>.   L’avantage de la déstructuration est que vous pouvez collecter les props non utilisés et utiliser l’opérateur de repos d’objet.

      Enregistrez et quittez le fichier. Lorsque vous le ferez, le navigateur se rechargera et vous verrez le nom spécifique de chaque animal au lieu d’un espace réservé.

      Projets React avec des noms d'animaux rendus

      La propriété name est une chaîne de caractères, mais les props peuvent être n’importe quel type de données que vous pourriez passer à une fonction JavaScript. Pour voir cela à l’œuvre, ajoutez le reste des données.

      Ouvrez le fichier App.js :

      • nano src/components/App/App.js

      Ajoutez un prop pour chacun des éléments suivants : scientificName, size, diet et additional. Ceux-ci comprennent des chaînes de caractères, des entiers, des tableaux et des objets.

      prop-tutorial/src/components/App/App.js

      import React from 'react';
      ...
      
      function App() {
        return (
          <div className="wrapper">
            <h1>Animals</h1>
            {albums.map(album => (
              <AnimalCard
                additional={animal.additional}
                diet={animal.diet}
                key={animal.name}
                name={animal.name}
                scientificName={animal.scientificName}
                size={animal.size}
              />
            ))}
          </div>
        )
      }
      
      export default App;
      

      Puisque vous créez un objet, vous pouvez les ajouter dans l’ordre que vous voulez. L’ordre alphabétique permet de parcourir plus facilement une liste de props, surtout dans une liste plus longue. Vous pouvez également les ajouter sur la même ligne, mais le fait de les séparer à une par ligne permet de garder les choses lisibles.

      Enregistrez et fermez le fichier. Ouvrez AnimalCard.js.

      • nano src/components/AnimalCard/AnimalCard.js

      Cette fois, déstructurez les props dans la liste des paramètres de fonction et utilisez les données dans le composant :

      prop-tutorial/src/components/AnimalCard/AnimalCard.js

      import React from 'react';
      import './AnimalCard.css'
      
      export default function AnimalCard({
        additional,
        diet,
        name,
        scientificName,
        size
      }) {
        return (
          <div>
            <h2>{name}</h2>
            <h3>{scientificName}</h3>
            <h4>{size}kg</h4>
            <div>{diet.join(', ')}.</div>
          </div>
        );
      }
      

      Après avoir extrait les données, vous pouvez ajouter scientificName et size dans les balises d’en-tête, mais vous devrez convertir le tableau en une chaîne pour que React puisse l’afficher sur la page. Vous pouvez le faire avec join(', '), ce qui créera une liste séparée par des virgules.

      Enregistrez et fermez le fichier. Lorsque vous le ferez, le navigateur se rafraîchira et vous verrez les données structurées.

      Projet React avec les animaux en disposant de données complètes

      Vous pourriez créer une liste similaire avec l’objet additional, mais en ajoutant une fonction pour alerter l’utilisateur avec les données. Cela vous donnera la possibilité de passer des fonctions comme props et d’utiliser ensuite les données à l’intérieur d’un composant lorsque vous appelez une fonction.

      Ouvrez App.js: 

      • nano src/components/App/App.js

      Créez une fonction appelée showAdditionalData qui convertira l’objet en une chaîne de caractères et l’affichera comme une alerte.

      prop-tutorial/src/components/App/App.js

      import React from 'react';
      ...
      
      function showAdditional(additional) {
        const alertInformation = Object.entries(additional)
          .map(information => `${information[0]}: ${information[1]}`)
          .join('n');
        alert(alertInformation)
      };
      
      function App() {
        return (
          <div className="wrapper">
            <h1>Animals</h1>
            {data.map(animal => (
              <AnimalCard
                additional={animal.additional}
                diet={animal.diet}
                key={animal.name}
                name={animal.name}
                scientificName={animal.scientificName}
                showAdditional={showAdditional}
                size={animal.size}
              />
            ))}
          </div>
        )
      }
      
      export default App;
      

      La fonction showAdditional convertit l’objet en un tableau de paires où le premier élément est la clé et le second la valeur. Elle établit ensuite une correspondance avec les données en convertissant la paire de clés en une chaîne. Puis elle les joint avec un saut de ligne – n avant de passer la chaîne complète à la fonction d’alerte.

      Comme JavaScript peut accepter des fonctions comme arguments, React peut également accepter des fonctions comme props. Vous pouvez donc passer showAdditional à AnimalCard comme un prop appelé showAdditional. 

      Enregistrez et fermez le fichier. Ouvrez AnimalCard :

      • nano src/components/AnimalCard/AnimalCard.js

      Tirez la fonction showAdditional de l’objet props, puis créez un <bouton> avec un événement onClick qui appelle la fonction avec l’objet additional :

      prop-tutorial/src/components/AnimalCard/AnimalCard.js

      import React from 'react';
      import './AnimalCard.css'
      
      export default function AnimalCard({
        additional,
        diet,
        name,
        scientificName,
        showAdditional,
        size
      }) {
        return (
          <div>
            <h2>{name}</h2>
            <h3>{scientificName}</h3>
            <h4>{size}kg</h4>
            <div>{diet.join(', ')}.</div>
            <button onClick={() => showAdditional(additional)}>More Info</button>
          </div>
        );
      }
      

      Sauvegardez le fichier. Lorsque vous le ferez, le navigateur se rafraîchira et vous verrez un bouton après chaque carte. Lorsque vous cliquez sur le bouton, vous obtenez une alerte avec les données supplémentaires.

      Alerte avec des informations

      Si vous essayez de cliquer sur Plus d’infos pour le Lion, vous obtiendrez une erreur. C’est parce qu’il n’y a pas de données supplémentaires pour le lion. Vous verrez comment régler ce problème à l’étape 3.

      Enfin, ajoutez un peu de style à la carte musicale. Ajoutez une classeNom de l’animal-wrapper à la div dans AnimalCard :

      prop-tutorial/src/components/AnimalCard/AnimalCard.js

      import React from 'react';
      import './AnimalCard.css'
      
      export default function AnimalCard({
      ...
        return (
          <div className="animal-wrapper">
      ...
          </div>
        )
      }
      

      Enregistrez et fermez le fichier. Ouvrez AnimalCard.css :

      • nano src/components/AnimalCard/AnimalCard.css

      Ajoutez du CSS pour donner aux cartes et au bouton une petite bordure et du padding :

      prop-tutorial/src/components/AnimalCard/AnimalCard.css

      .animal-wrapper {
          border: solid black 1px;
          margin: 10px;
          padding: 10px;
          width: 200px;
      }
      
      .animal-wrapper button {
          font-size: 1em;
          border: solid black 1px;
          padding: 10;
          background: none;
          cursor: pointer;
          margin: 10px 0;
      }
      

      Ce CSS ajoutera une légère bordure à la carte et remplacera le style du bouton par défaut par une bordure et du paddding. cursor: pointer changera le curseur lorsque vous passerez sur le bouton. 

      Enregistrez et fermez le fichier. Lorsque vous le faites, le navigateur se rafraîchit et vous voyez les données dans les cartes individuelles.

      Projet React avec des cartes d'animaux stylisés

      À ce stade, vous avez créé deux composants personnalisés. Vous avez transmis des données au deuxième composant à partir du premier composant en utilisant des props. Les props incluent une variété de données, telles que des chaînes de caractères, des entiers, des tableaux, des objets et des fonctions. Dans votre deuxième composant, vous avez utilisé les props pour créer un composant dynamique en utilisant JSX.

      Dans l’étape suivante, vous utiliserez un système de types appelé prop-types pour spécifier la structure que votre composant s’attend à voir, ce qui créera de la prévisibilité dans votre application et empêchera les bugs.

      Étape 3 – Créer des props prévisibles avec les PropTypes et les defaultProps

      Dans cette étape, vous ajouterez un système de type léger à vos composants avec PropTypes. Les PropTypes agissent comme les autres systèmes de type en définissant explicitement le type de données que vous vous attendez à recevoir pour un certain prop. Ils vous donnent également la possibilité de définir des données par défaut dans les cas où le prop n’est pas toujours nécessaire. Contrairement à la plupart des systèmes de types, PropTypes est une vérification d’exécution, donc si les accessoires ne correspondent pas au type, le code se compilera quand même, mais affichera aussi une erreur de console.

      À la fin de cette étape, vous ajouterez de la prévisibilité à votre composant personnalisé en définissant le type de chaque prop. Ainsi, la prochaine personne qui travaillera sur le composant aura une idée claire de la structure des données dont le composant aura besoin.

      Le paquet prop-types est inclus dans l’installation de Create React App ; donc pour l’utiliser, il vous suffit de l’importer dans votre composant.

      Ouvrez AnimalCard.js :

      • nano src/components/AnimalCard/AnimalCard.js

      Ensuite, importez les PropTypes à partir des prop-types : 

      prop-tutorial/src/components/AnimalCard/AnimalCard.js

      import React from 'react';
      import PropTypes from 'prop-types';
      import './AnimalCard.css'
      
      export default function AnimalCard({
      ...
      }
      

      Ajoutez PropTypes directement à la fonction du composant.   En JavaScript, les fonctions sont des objets, ce qui signifie que vous pouvez ajouter des propriétés en utilisant la syntaxe des points. Ajoutez les PropTypes suivants à AnimalCard.js :

      prop-tutorial/src/components/AnimalCard/AnimalCard.js

      import React from 'react';
      import PropTypes from 'prop-types';
      import './AnimalCard.css'
      
      export default function AnimalCard({
      ...
      }
      
      AnimalCard.propTypes = {
        additional: PropTypes.shape({
          link: PropTypes.string,
          notes: PropTypes.string
        }),
        diet: PropTypes.arrayOf(PropTypes.string).isRequired,
        name: PropTypes.string.isRequired,
        scientificName: PropTypes.string.isRequired,
        showAdditional: PropTypes.func.isRequired,
        size: PropTypes.number.isRequired,
      }
      

      Enregistrez et fermez le fichier.

      Comme vous pouvez le voir, il existe de nombreux types de PropTypes différents. Ce n’est qu’un petit échantillon ; consultez la documentation officielle de React pour voir les autres que vous pouvez utiliser.

      Commençons par le prop name. Ici, vous spécifiez que name doit être une chaîne de caractères. La propriété scientificName est la même. size est un nombre, qui peut inclure à la fois des flotteurs comme 1,5 et des entiers comme 6. showAdditional est une fonction (func).

      diet, en revanche, est un peu différent. Dans ce cas, vous spécifiez que diet sera un tableau, mais vous devez également préciser ce que ce tableau contiendra. Dans ce cas, le tableau ne contiendra que des chaînes de caractères. Si vous voulez mélanger les types, vous pouvez utiliser un autre prop appelé oneOfType qui prend un ensemble de PropTypes valides. Vous pouvez utiliser oneOfType n’importe où, donc si vous voulez que size soit soit un nombre ou une chaîne, vous pouvez la changer en ceci : 

      size: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
      

      Le prop additional est également un peu plus complexe. Dans ce cas, vous spécifiez un objet, mais pour être un peu plus clair, vous indiquez ce que vous voulez que l’objet contienne. Pour ce faire, vous utilisezPropTypes.shape, qui prend un objet avec des champs supplémentaires qui auront besoin de leurs propres PropTypes. Dans ce cas, link et notes sont tous deux PropTypes.string.

      Actuellement, toutes les données sont bien formées et correspondent aux props. Pour voir ce qui se passe si les PropTypes ne correspondent pas, ouvrez vos données :

      • nano src/components/App/data.js

      Changez la size en une chaîne sur le premier article :

      prop-tutorial/src/components/App/data.js

      export default [
        {
          name: 'Lion',
          scientificName: 'Panthero leo',
          size: '140',
          diet: ['meat'],
        },
      ...
      ]
      

      Sauvegardez le fichier. Lorsque vous le faites, le navigateur se rafraîchit et vous voyez une erreur dans la console.

      Error

      index.js:1 Warning: Failed prop type: Invalid prop `size` of type `string` supplied to `AnimalCard`, expected `number`. in AnimalCard (at App.js:18) in App (at src/index.js:9) in StrictMode (at src/index.js:8)

      Navigateur avec erreur de frappe

      Contrairement à d’autres systèmes de types tels que TypeScript, PropTypes ne vous donnera pas d’avertissement au moment de la construction, et tant qu’il n’y a pas d’erreurs de code, il continuera à se compiler. Cela signifie que vous pourriez accidentellement publier du code avec des erreurs de props.

      Remplacez les données par le type correct :

      prop-tutorial/src/components/App/data.js

      export default [
        {
          name: 'Lion',
          scientificName: 'Panthero leo',
          size: 140,
          diet: ['meat'],
        },
      ...
      ]
      

      Enregistrez et fermez le fichier.

      Ouvrez AnimalCard.js :

      • nano src/components/AnimalCard/AnimalCard.js

      Tous les props, à l’exception d’additional a la propriété isRequired.  Cela signifie qu’ils sont nécessaires. Si vous n’incluez pas un prop requis, le code se compilera quand même, mais vous verrez une erreur d’exécution dans la console.

      Si un prop n’est pas nécessaire, vous pouvez ajouter une valeur par défaut. Il est de bonne pratique de toujours ajouter une valeur par défaut pour éviter les erreurs d’exécution si un prop n’est pas nécessaire. Par exemple, dans le composant AnimalCard, vous appelez une fonction avec la donnée additional. Si elle n’est pas là, la fonction va essayer de modifier un objet qui n’existe pas et l’application va planter.

      Pour éviter ce problème, ajoutez un defaultProp pour additional :

      prop-tutorial/src/components/AnimalCard/AnimalCard.js

      import React from 'react';
      import PropTypes from 'prop-types';
      import './AnimalCard.css'
      
      export default function AnimalCard({
      ...
      }
      
      AnimalCard.propTypes = {
        additional: PropTypes.shape({
          link: PropTypes.string,
          notes: PropTypes.string
        }),
      ...
      }
      
      AnimalCard.defaultProps = {
        additional: {
          notes: 'No Additional Information'
        }
      }
      

      Vous ajoutez le defaultProps à la fonction en utilisant la syntaxe des points comme vous l’avez fait avec propTypes, puis vous ajoutez une valeur par défaut que le composant doit utiliser si le prop est undefined. Dans ce cas, vous faites correspondre la forme d'additional, y compris un message indiquant qu’il n’y a pas d’informations supplémentaires.

      Enregistrez et fermez le fichier. Lorsque vous le faites, le navigateur se rafraîchit. Après l’avoir actualisé, cliquez sur le bouton More info pour Lion. Il n’y a pas de champ additional dans les données, donc le prop est undefined.   Mais AnimalCard se substituera au prop par défaut.

      Navigateur avec message par défaut dans l'alerte

      Vos props sont désormais bien documentés et sont soit obligatoires, soit dotés d’une valeur par défaut pour garantir un code prévisible. Cela aidera les futurs développeurs (y compris vous-même) à comprendre les props dont un composant a besoin. Cela facilitera l’échange et la réutilisation de vos composants en vous donnant des informations complètes sur la manière dont le composant utilisera les données qu’il reçoit.

      Conclusion

      Dans ce tutoriel, vous avez créé plusieurs composants qui utilisent des props pour afficher les informations d’un parent. Les props vous donnent la souplesse nécessaire pour commencer à briser les gros composants en morceaux plus petits et plus ciblés. Maintenant que vous n’avez plus vos données étroitement couplées à vos informations d’affichage, vous avez la possibilité de faire des choix sur la manière de segmenter votre application.

      Les props sont un outil crucial dans la construction d’applications complexes, donnant la possibilité de créer des composants qui peuvent s’adapter aux données qu’ils reçoivent. Avec les PropTypes, vous créez des composants prévisibles et lisibles qui donneront à une équipe la possibilité de réutiliser le travail de chacun pour créer une base de code souple et stable. Si vous souhaitez consulter d’autres tutoriels de la série React, consultez notre page thématique React ou retournez à la page de la série Comment coder en React.js. 



      Source link

      Comprendre la déstructuration, les paramètres de rest et la syntaxe Spread en JavaScript


      L’auteur a choisi le COVID-19 Relief Fund pour recevoir un don dans le cadre du programme Write for DOnations.

      Introduction

      De nombreuses nouvelles fonctionnalités permettant de travailler avec des tableaux et des objets ont été mises à la disposition du langage JavaScript depuis l’édition 2015 de la spécification ECMAScript. Quelques-uns des éléments notables que vous apprendrez dans cet article sont la déstructuration, les paramètres de rest et la syntaxe de spread. Ces fonctionnalités fournissent des moyens plus directs d’accéder aux membres d’un tableau ou d’un objet, et peuvent rendre le travail avec ces structures de données plus rapide et plus succinct.

      De nombreux autres langages n’ont pas de syntaxe correspondante pour la déstructuration, les paramètres de rest et spread, de sorte que ces caractéristiques peuvent avoir une courbe d’apprentissage à la fois pour les nouveaux développeurs JavaScript et ceux qui viennent d’un autre langage. Dans cet article, vous apprendrez comment déstructurer des objets et des tableaux, comment utiliser l’opérateur de spread pour décompresser des objets et des tableaux, et comment utiliser les paramètres de rest dans les appels de fonction.

      Déstructurer

      L’affectation de déstructuration est une syntaxe qui vous permet d’affecter des propriétés d’objets ou des éléments de tableau comme variables. Cela peut réduire considérablement les lignes de code nécessaires pour manipuler les données dans ces structures. Il existe deux types de déstructuration : Déstructuration d’objets et déstructuration des tableaux.

      Déstructuration d’objets

      La déstructuration d’objets vous permet de créer de nouvelles variables en utilisant une propriété de l’objet comme valeur.

      Prenons cet exemple, un objet qui représente une note avec une id, un titre et une date :

      const note = {
        id: 1,
        title: 'My first note',
        date: '01/01/1970',
      }
      

      Traditionnellement, si vous vouliez créer une nouvelle variable pour chaque propriété, vous deviez affecter chaque variable individuellement, avec beaucoup de répétition :

      // Create variables from the Object properties
      const id = note.id
      const title = note.title
      const date = note.date
      

      Avec la déstructuration des objets, tout cela peut être fait en une seule ligne. En entourant chaque variable d’accolades {}, JavaScript créera de nouvelles variables à partir de chaque propriété portant le même nom :

      // Destructure properties into variables
      const { id, title, date } = note
      

      Maintenant, console.log() les nouvelles variables :

      console.log(id)
      console.log(title)
      console.log(date)
      

      Vous obtiendrez les valeurs initiales des valeurs des propriétés comme résultat :

      Output

      1 My first note 01/01/1970

      Note : La déstructuration d’un objet ne modifie pas l’objet original. Vous pouvez toujours appeler la note originale avec toutes ses entrées intactes.

      L’affectation par défaut pour la déstructuration des objets crée de nouvelles variables portant le même nom que la propriété de l’objet. Si vous ne souhaitez pas que la nouvelle variable ait le même nom que le nom de la propriété, vous avez également la possibilité de renommer la nouvelle variable en utilisant deux-points ( : ) pour décider d’un nouveau nom, comme on le verra avec la noteId dans ce qui suit :

      // Assign a custom name to a destructured value
      const { id: noteId, title, date } = note
      

      Enregistrez la nouvelle variable noteId dans la console :

      console.log(noteId)
      

      Vous recevrez le résultat suivant :

      Output

      1

      Vous pouvez également déstructurer les valeurs d’objets imbriqués. Par exemple, mettez à jour l’objet note pour avoir un objet auteur imbriqué :

      const note = {
        id: 1,
        title: 'My first note',
        date: '01/01/1970',
        author: {
          firstName: 'Sherlock',
          lastName: 'Holmes',
        },
      }
      

      Vous pouvez maintenant déstructurer note, puis déstructurer à nouveau pour créer des variables à partir des propriétés de l'auteur :

      // Destructure nested properties
      const {
        id,
        title,
        date,
        author: { firstName, lastName },
      } = note
      

      Ensuite, enregistrez les nouvelles variables firstName et lastName en utilisant les littéraux du modèle :

      console.log(`${firstName} ${lastName}`)
      

      Cela donnera le résultat suivant :

      Output

      Sherlock Holmes

      Notez que dans cet exemple, bien que vous ayez accès au contenu de l’objet auteur, l’objet auteur lui-même n’est pas accessible. Pour accéder à un objet ainsi qu’à ses valeurs imbriquées, il faudrait les déclarer séparément :

      // Access object and nested values
      const {
        author,
        author: { firstName, lastName },
      } = note
      
      console.log(author)
      

      Ce code produira l’objet author:

      Output

      {firstName: "Sherlock", lastName: "Holmes"}

      La déstructuration d’un objet n’est pas seulement utile pour réduire la quantité de code que vous devez écrire ; elle vous permet également de cibler votre accès aux propriétés qui vous intéressent.

      Enfin, déstructurer peut être utilisé pour accéder aux propriétés des objets des valeurs primitives. Par exemple, String est un objet global pour les chaînes de caractères, et possède une propriété de longueur :

      const { length } = 'A string'
      

      Cela permettra de trouver la propriété de longueur inhérente d’une chaîne et de la rendre égale à la variable de longueur. Enregistrez la longueur pour voir si cela a fonctionné :

      console.log(length)
      

      Vous aurez le résultat suivant :

      Output

      8

      La chaîne A string a été implicitement convertie en un objet ici pour récupérer la propriété de longueur.

      Déstructuration des tableaux

      La déstructuration des tableaux vous permet de créer de nouvelles variables en utilisant un élément de tableau comme valeur. Prenons cet exemple, un tableau avec les différentes parties d’une date :

      const date = ['1970', '12', '01']
      

      Les tableaux en JavaScript sont garantis pour préserver leur ordre, donc dans ce cas le premier indice sera toujours une année, le second sera le mois, et ainsi de suite. Sachant cela, vous pouvez créer des variables à partir des éléments du tableau :

      // Create variables from the Array items
      const year = date[0]
      const month = date[1]
      const day = date[2]
      

      Mais le faire manuellement peut prendre beaucoup de place dans votre code. Avec la déstructuration des tableaux, vous pouvez décomposer les valeurs du tableau dans l’ordre et les affecter à leurs propres variables, comme ceci :

      // Destructure Array values into variables
      const [year, month, day] = date
      

      Enregistrez maintenant les nouvelles variables :

      console.log(year)
      console.log(month)
      console.log(day)
      

      Vous aurez le résultat suivant :

      Output

      1970 12 01

      Les valeurs peuvent être sautées en laissant la syntaxe de déstructuration vide entre les virgules :

      // Skip the second item in the array
      const [year, , day] = date
      
      console.log(year)
      console.log(day)
      

      L’exécution de cette opération donnera la valeur de l'année et du jour :

      Output

      1970 01

      Les tableaux imbriqués peuvent également être déstructurés. Tout d’abord, créez un tableau imbriqué :

      // Create a nested array
      const nestedArray = [1, 2, [3, 4], 5]
      

      Ensuite, déstructurez ce tableau et enregistrez les nouvelles variables :

      // Destructure nested items
      const [one, two, [three, four], five] = nestedArray
      
      console.log(one, two, three, four, five)
      

      Vous recevrez le résultat suivant :

      Output

      1 2 3 4 5

      La syntaxe de déstructuration peut être appliquée pour déstructurer les paramètres d’une fonction. Pour tester cela, vous déstructurez les clés et les valeurs à partir de Object.entries().

      Déclarez d’abord l’objet de la note :

      const note = {
        id: 1,
        title: 'My first note',
        date: '01/01/1970',
      }
      

      Étant donné cet objet, vous pourriez dresser la liste des paires clé-valeur en déstructurant les arguments au fur et à mesure qu’ils sont passés à la méthode forEach() :

      // Using forEach
      Object.entries(note).forEach(([key, value]) => {
        console.log(`${key}: ${value}`)
      })
      

      Ou vous pourriez faire la même chose en utilisant une boucle for :

      // Using a for loop
      for (let [key, value] of Object.entries(note)) {
        console.log(`${key}: ${value}`)
      }
      

      Dans tous les cas, vous recevrez ce qui suit :

      Output

      id: 1 title: My first note date: 01/01/1970

      La déstructuration d’objets et la déstructuration de tableaux peuvent être combinées en une seule affectation de déstructuration. Les paramètres par défaut peuvent également être utilisés avec la déstructuration, comme le montre cet exemple qui fixe la date par défaut à new Date().

      Déclarez d’abord l’objet de la note :

      const note = {
        title: 'My first note',
        author: {
          firstName: 'Sherlock',
          lastName: 'Holmes',
        },
        tags: ['personal', 'writing', 'investigations'],
      }
      

      Puis déstructurez l’objet, tout en définissant une nouvelle variable de date avec la valeur par défaut de new Date() :

      const {
        title,
        date = new Date(),
        author: { firstName },
        tags: [personalTag, writingTag],
      } = note
      
      console.log(date)
      

      console.log(date) donnera alors un résultat similaire à ce qui suit :

      Output

      Fri May 08 2020 23:53:49 GMT-0500 (Central Daylight Time)

      Comme le montre cette section, la syntaxe de l’affectation de déstructuration ajoute beaucoup de souplesse à JavaScript et permet d’écrire un code plus succinct. Dans la section suivante, vous verrez comment la syntaxe de spread peut être utilisée pour étendre les structures de données dans leurs entrées de données constitutives.

      Spread

      La syntaxe Spread (...) est un autre ajout utile au JavaScript pour travailler avec des tableaux, des objets et des appels de fonction. Spread permet de déballer ou d’étendre des objets et des itérables (tels que des tableaux), qui peuvent être utilisés pour faire des copies superficielles de structures de données afin d’accroître la facilité de manipulation des données.

      Spread avec des tableaux

      Spread peut simplifier les tâches courantes avec les tableaux. Par exemple, disons que vous avez deux tableaux et que vous voulez les combiner :

      // Create an Array
      const tools = ['hammer', 'screwdriver']
      const otherTools = ['wrench', 'saw']
      

      A l’origine, vous deviez utiliser concat() pour concaténer les deux tableaux :

      // Concatenate tools and otherTools together
      const allTools = tools.concat(otherTools)
      

      Désormais, vous pouvez également utiliser spread pour déballer les tableaux dans un nouveau tableau :

      // Unpack the tools Array into the allTools Array
      const allTools = [...tools, ...otherTools]
      
      console.log(allTools)
      

      L’exécution de cette opération donnerait les résultats suivants :

      Output

      ["hammer", "screwdriver", "wrench", "saw"]

      Cela peut être particulièrement utile en cas d’immuabilité. Par exemple, vous pourriez travailler avec une application dont les utilisateurs sont stockés dans un ensemble d’objets : 

      // Array of users
      const users = [
        { id: 1, name: 'Ben' },
        { id: 2, name: 'Leslie' },
      ]
      

      Vous pourriez utiliserpush pour modifier le tableau existant et ajouter un nouvel utilisateur, ce qui serait l’option mutable :

      // A new user to be added
      const newUser = { id: 3, name: 'Ron' }
      
      users.push(newUser)
      

      Mais cela change le tableau user, que nous pourrions vouloir conserver.

      Spread vous permet de créer un nouveau tableau à partir de celui qui existe déjà et d’ajouter un nouvel élément à la fin :

      const updatedUsers = [...users, newUser]
      
      console.log(users)
      console.log(updatedUsers)
      

      Maintenant, le nouveau tableau, updatedUsers, a le nouvel utilisateur, mais le tableau original users reste inchangé :

      Output

      [{id: 1, name: "Ben"} {id: 2, name: "Leslie"}] [{id: 1, name: "Ben"} {id: 2, name: "Leslie"} {id: 3, name: "Ron"}]

      Créer des copies de données au lieu de modifier les données existantes peut aider à prévenir les changements inattendus. En JavaScript, lorsque vous créez un objet ou un tableau et que vous l’affectez à une autre variable, vous ne créez pas réellement un nouvel objet – vous passez une référence.

      Prenez cet exemple, dans lequel un tableau est créé et assigné à une autre variable :

      // Create an Array
      const originalArray = ['one', 'two', 'three']
      
      // Assign Array to another variable
      const secondArray = originalArray
      

      Supprimer le dernier élément du deuxième tableau modifiera le premier :

      // Remove the last item of the second Array
      secondArray.pop()
      
      console.log(originalArray)
      

      Cela donnera le résultat :

      Output

      ["one", "two"]

      Spread vous permet de faire une copie superficielle d’un tableau ou d’un objet, ce qui signifie que toutes les propriétés de haut niveau seront clonées, mais que les objets imbriqués seront toujours passés par référence. Pour les tableaux ou objets simples, une copie superficielle peut suffire.

      Si vous écrivez le même exemple de code mais copiez le tableau avec spread, le tableau original ne sera plus modifié :

      // Create an Array
      const originalArray = ['one', 'two', 'three']
      
      // Use spread to make a shallow copy
      const secondArray = [...originalArray]
      
      // Remove the last item of the second Array
      secondArray.pop()
      
      console.log(originalArray)
      

      Les éléments suivants seront enregistrés sur la console :

      Output

      ["one", "two", "three"]

      Spread peut également être utilisé pour convertir un set, ou tout autre iterable, en un tableau.

      Créez un nouvel ensemble et ajoutez-y quelques entrées :

      // Create a set
      const set = new Set()
      
      set.add('octopus')
      set.add('starfish')
      set.add('whale')
      

      Ensuite, utilisez l’opérateur spread avec set et enregistrez les résultats :

      // Convert Set to Array
      const seaCreatures = [...set]
      
      console.log(seaCreatures)
      

      Cela donnera le résultat :

      Output

      ["octopus", "starfish", "whale"]

      Cela peut également être utile pour créer un tableau à partir d’une chaîne de caractères :

      const string = 'hello'
      
      const stringArray = [...string]
      
      console.log(stringArray)
      

      Cela donnera un tableau avec chaque caractère en tant qu’élément dans le tableau :

      Output

      ["h", "e", "l", "l", "o"]

      Spread avec objets

      Lorsqu’on travaille avec des objets, spread peut être utilisé pour copier et mettre à jour les objets.

      A l’origine, Object.assign() était utilisé pour copier un objet :

      // Create an Object and a copied Object with Object.assign()
      const originalObject = { enabled: true, darkMode: false }
      const secondObject = Object.assign({}, originalObject)
      

      Le secondObject sera désormais un clone de l’originalObject.

      La syntaxe de spread simplifie cette opération (vous pouvez copier un objet superficiellement en l’étalant dans un nouvel objet) :

      // Create an object and a copied object with spread
      const originalObject = { enabled: true, darkMode: false }
      const secondObject = { ...originalObject }
      
      console.log(secondObject)
      

      Ce qui donnera le résultat suivant :

      Output

      {enabled: true, darkMode: false}

      Tout comme pour les tableaux, cela ne créera qu’une copie superficielle, et les objets imbriqués seront toujours passés par référence.

      L’ajout ou la modification de propriétés sur un objet existant de manière immuable est simplifié avec spread. Dans cet exemple, la propriété isLoggedIn est ajoutée à l’objet user:

      const user = {
        id: 3,
        name: 'Ron',
      }
      
      const updatedUser = { ...user, isLoggedIn: true }
      
      console.log(updatedUser)
      

      Il en résultera ce qui suit :

      Output

      {id: 3, name: "Ron", isLoggedIn: true}

      Une chose importante à noter concernant la mise à jour des objets spread est que tout objet imbriqué devra également être diffusé. Par exemple, disons que dans l’objet user, il y a un objet organisationnel imbriqué :

      const user = {
        id: 3,
        name: 'Ron',
        organization: {
          name: 'Parks & Recreation',
          city: 'Pawnee',
        },
      }
      

      Si vous essayez d’ajouter un nouvel élément à l’organisation, il écrasera les champs existants : 

      const updatedUser = { ...user, organization: { position: 'Director' } }
      
      console.log(updatedUser)
      

      Ce qui donnera le résultat suivant :

      Output

      id: 3 name: "Ron" organization: {position: "Director"}

      Si la mutabilité n’est pas un problème, le champ pourrait être mis à jour directement :

      user.organization.position = 'Director'
      

      Mais comme nous recherchons une solution immuable, nous pouvons diffuser l’objet intérieur pour conserver les propriétés existantes :

      const updatedUser = {
        ...user,
        organization: {
          ...user.organization,
          position: 'Director',
        },
      }
      
      console.log(updatedUser)
      

      Cela donnera le résultat :

      Output

      id: 3 name: "Ron" organization: {name: "Parks & Recreation", city: "Pawnee", position: "Director"}

      Spread avec appels de fonction

      Spread peut également être utilisé avec les arguments dans les appels de fonction.

      Par exemple, voici une fonction multiply qui prend trois paramètres et les multiplie.

      // Create a function to multiply three items
      function multiply(a, b, c) {
        return a * b * c
      }
      

      Normalement, vous feriez passer trois valeurs individuellement comme arguments à l’appel de fonction, comme ceci :

      multiply(1, 2, 3)
      

      Cela donnerait ce qui suit :

      Output

      6

      Cependant, si toutes les valeurs que vous voulez passer à la fonction existent déjà dans un tableau, la syntaxe de spread vous permet d’utiliser chaque élément d’un tableau comme argument :

      const numbers = [1, 2, 3]
      
      multiply(...numbers)
      

      Cela donnera le même résultat :

      Output

      6

      Note : Sans spread, ceci peut être réalisé en utilisant apply() :

      multiply.apply(null, [1, 2, 3])
      

      Il en résultera :

      Output

      6

      Maintenant que vous avez vu comment spread peut raccourcir votre code, vous pouvez vous pencher sur une utilisation différente de la syntaxe ... : les paramètres de rest.

      Les paramètres de Rest

      La dernière caractéristique que vous apprendrez dans cet article est la syntaxe des paramètres de rest. La syntaxe est la même que celle de spread (...) mais a l’effet inverse. Au lieu de décomposer un tableau ou un objet en valeurs individuelles, la syntaxe de rest va créer un tableau d’un nombre indéfini d’arguments.

      Dans la fonction restTest par exemple, si nous voulions qu’args soit un tableau composé d’un nombre indéfini d’arguments, on pourrait avoir ce qui suit : 

      function restTest(...args) {
        console.log(args)
      }
      
      restTest(1, 2, 3, 4, 5, 6)
      

      Tous les arguments transmis à la fonction restTest sont maintenant disponibles dans le tableau des args : 

      Output

      [1, 2, 3, 4, 5, 6]

      La syntaxe de Rest peut être utilisée comme seul paramètre ou comme dernier paramètre de la liste. S’il est utilisé comme seul paramètre, il rassemblera tous les arguments, mais s’il se trouve à la fin d’une liste, il rassemblera tous les arguments qui restent, comme on le voit dans cet exemple :

      function restTest(one, two, ...args) {
        console.log(one)
        console.log(two)
        console.log(args)
      }
      
      restTest(1, 2, 3, 4, 5, 6)
      

      Il s’agira de prendre les deux premiers arguments individuellement, puis de regrouper le reste dans un tableau :

      Output

      1 2 [3, 4, 5, 6]

      Dans l’ancien code, la variable arguments pouvait être utilisée pour rassembler tous les arguments transmis à une fonction :

      function testArguments() {
        console.log(arguments)
      }
      
      testArguments('how', 'many', 'arguments')
      

      Cela donnerait le résultat suivant :

      Output

      1Arguments(3) ["how", "many", "arguments"]

      Toutefois, cela présente quelques inconvénients. Premièrement, la variable arguments ne peut pas être utilisée avec les fonctions flèches.

      const testArguments = () => {
        console.log(arguments)
      }
      
      testArguments('how', 'many', 'arguments')
      

      Cela entraînerait une erreur :

      Output

      Uncaught ReferenceError: arguments is not defined

      En outre, arguments n’est pas un véritable tableau et ne peut pas utiliser des méthodes comme map et filter sans être préalablement converti en un tableau. Il recueillera également tous les arguments passés au lieu de se limiter au reste des arguments, comme on le voit dans l’exemple restTest (one, two, ...args).

      Rest peut également être utilisé lors de la déstructuration des tableaux :

      const [firstTool, ...rest] = ['hammer', 'screwdriver', 'wrench']
      
      console.log(firstTool)
      console.log(rest)
      

      Il en résultera :

      Output

      hammer ["screwdriver", "wrench"]

      Rest peut également être utilisé lors de la déstructuration d’objets :

      const { isLoggedIn, ...rest } = { id: 1, name: 'Ben', isLoggedIn: true }
      
      console.log(isLoggedIn)
      console.log(rest)
      

      En donnant le résultat suivant :

      Output

      true {id: 1, name: "Ben"}

      De cette façon, la syntaxe de rest fournit des méthodes efficaces pour rassembler une quantité indéterminée d’éléments.

      Conclusion

      Dans cet article, vous avez appris des choses sur la déstructuration, la syntaxe de spread et les paramètres de rest. En résumé :

      • La déstructuration est utilisée pour créer des variables à partir d’éléments de tableau ou de propriétés d’objets.
      • La syntaxe de spread est utilisée pour décompresser les itérables tels que les tableaux, les objets et les appels de fonction.
      • La syntaxe des paramètres de rest crée un tableau à partir d’un nombre indéfini de valeurs.

      La déstructuration, les paramètres de repos et la syntaxe de spread sont des fonctions utiles de JavaScript qui aident à maintenir votre code succinct et propre.

      Si vous souhaitez voir la déstructuration en action, consultez Comment personnaliser les éléments de React avec des props qui utilise cette syntaxe pour déstructurer les données et les transmettre à des composants frontaux personnalisés. Si vous souhaitez en savoir plus sur JavaScript, retournez à notre Page de la série Comment coder en JavaScript. 



      Source link