One place for hosting & domains

      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

      Cómo personalizar componentes de React con props


      El autor seleccionó Creative Commons para recibir una donación como parte del programa Write for DOnations.

      Introducción

      A través de este tutorial, creará componentes personalizados pasando props a su componente. Los props son argumentos que se proporcionan a un elemento JSX. Se parecen a los props HTML estándares, pero no están predefinidos y pueden tener varios tipos de datos de JavaScript, incluidos números, cadenas, funciones, matrices e incluso otros componentes de React. Sus componentes personalizados pueden utilizar props para mostrar datos o utilizar los datos para hacer que los componentes sean interactivos. Los props son un elemento clave en la creación de componentes que se adaptan a situaciones diferentes, y aprender sobre ellos le proporcionará las herramientas necesarias para desarrollar componentes personalizados que puedan manejar situaciones únicas.

      Después de añadir props a su componente, usará PropTypes para definir el tipo de datos que espera que reciba un componente. Los PropTypes son un sistema de tipo sencillo que comprueba que los datos coincidan con los tipos previstos durante el tiempo de ejecución. Sirven como documentación y como un verificador de errores que le ayudará a hacer que su aplicación sea predecible durante su escalamiento.

      Al final del tutorial, usará diferentes props para crear una aplicación pequeña que tome una matriz de datos de animales y muestre la información, incluidos el nombre común, el nombre científico, el tamaño, la dieta y datos adicionales.

      Nota: En el primer paso se establece un proyecto en blanco sobre el cual creará el ejercicio de tutorial. Si ya tiene un proyecto de trabajo y desea empezar directamente a trabajar con props, comience con el paso 2.

      Requisitos previos

      Paso 1: Crear un proyecto vacío

      En este paso, creará un nuevo proyecto usando Create React App. Luego, eliminará el proyecto de ejemplo y los archivos relacionados que se instalan al iniciar el proyecto. Por último, creará una estructura de archivos simple para organizar sus componentes.

      Para comenzar, cree un nuevo proyecto. En su línea de comandos, ejecute la siguiente secuencia de comandos para instalar un proyecto nuevo usando create-react-app​​​1​​:

      • npx create-react-app prop-tutorial

      Al finalizar el proyecto, posiciónese en el directorio:

      En una nueva pestaña o ventana de terminal, inicie el proyecto usando la secuencia de comandos de inicio de Create React App. El navegador actualizará los cambios automáticamente; deje que esta secuencia de comandos se ejecute mientras trabaja:

      Obtendrá un servidor local activo. Si el proyecto no se abrió en una ventana de navegador, puede encontrarlo en http://localhost:3000/. Si lo ejecuta desde un servidor remoto, la dirección será http://your_domain:3000.

      Su navegador se cargará con una aplicación de React sencilla incluida como parte de la aplicación de Create React App:

      Proyecto de plantilla de React

      Creará un conjunto completamente nuevo de componentes personalizados. Comenzará limpiando código de texto estándar para poder tener un proyecto vacío.

      Empiece abriendo src/App.js en un editor de texto. Es el componente root que se inserta en la página. Todos los componentes empezarán desde aquí. Puede obtener más información sobre App.js en Cómo configurar un proyecto de React con Create React App.

      Abra src/App.js con el siguiente comando:

      Verá un archivo como este:

      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;
      

      Elimine la línea import logo from './logo.svg';​​​. Luego, sustituya todo en instrucción return para mostrar un conjunto de etiquetas vacías: <</>. Esto le proporcionará una página de validación que no muestra nada. El código final tendrá el siguiente aspecto:

      prop-tutorial/src/App.js

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

      Guárdelo y salga del editor de texto.

      Por último, elimine el logo. No lo usará en su aplicación y debería eliminar los archivos que no se usen a medida que el trabajo avance. Le evitará confusiones en el futuro.

      En la ventana de la terminal, escriba el siguiente comando:

      Si observa su navegador, verá una pantalla en blanco.

      Pantalla en blanco en Chrome

      Ahora que limpió el proyecto Create React App, cree una estructura de archivos sencilla. Esto le permitirá mantener sus componentes aislados y preservar su independencia.

      Cree un directorio llamado components en el directorio src. Este contendrá todos sus componentes personalizados.

      Cada componente tendrá su propio directorio para almacenar el archivo de componentes junto con los estilos, las imágenes, si hay alguna, y las pruebas.

      Cree un directorio para App:

      Mueva todos los archivos de la App a ese directorio. Utilice el comodín, *, para seleccionar cualquier archivo que empiece con App. sin importar la extensión. Luego, utilice el comando mv para disponerlos en el directorio nuevo.

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

      Por último, actualice la ruta de importación relativa en index.js, el componente root que inicia todo el proceso.

      La instrucción import debe apuntar al archivo App.js en el directorio App; realice el siguiente cambio resaltado:

      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();
      

      Guarde el archivo y ciérrelo.

      Ahora que el proyecto está configurado, puede crear su primer componente.

      Paso 2: Crear componentes dinámicos con props

      En este paso, creará un componente llamado props, que se modificará sobre la base de la información de entrada. Los props son los argumentos que se pasan a una función o clase; sin embargo, dado que sus componentes se transforman en objetos HTML con JSX, pasará los props como si fueran atributos HTML. A diferencia de lo que sucede con los elementos HTML, puede pasar diferentes tipos de datos; desde cadenas, hasta matrices y objetos e incluso funciones.

      Aquí creará un componente que mostrará información sobre animales. Este componente tomará el nombre común y el nombre científico del animal como cadenas, el tamaño como entero, la dieta como una matriz de cadenas y la información adicional como un objeto. Pasará la información al nuevo componente como props y consumirá esa información en su componente.

      Al final de este paso, dispondrá de un componente personalizado que consumirá props diferentes. También usted reutilizará el componente para mostrar una matriz de datos utilizando un componente común.

      Agregar datos

      Primero, necesita algunos datos de ejemplo. Cree un archivo llamado “data” en el directorio src/App.

      • touch src/components/App/data.js

      Abra el nuevo archivo en su editor de texto:

      • nano src/components/App/data.js

      A continuación, agregue una matriz de objetos que usará como datos de ejemplo:

      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'
          }
        }
      ]
      

      La matriz de objetos contiene diferentes datos y le brindará la oportunidad de probar varios props. Cada objeto es un animal diferente con nombre de animal, nombre científico, tamaño, dieta y un campo opcional llamado additional, que contendrá enlaces o notas. En este código, también exportó la matriz como default.

      Guarde el archivo y ciérrelo.

      Crear componentes

      A continuación, cree un componente marcador de posición llamado AnimalCard. Llegado el momento, este componente tomará props y mostrará los datos.

      Primero, cree un directorio en src/components llamado AnimalCard y luego aplique touch a un archivo llamado src/components/AnimalCard/AnimalCard.js​ ​​y a un archivo CSS llamado src/components/AnimalCard/AnimalCard.css.

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

      Abra AnimalCard.js en su editor de texto:

      • nano src/components/AnimalCard/AnimalCard.js

      Añada un componente básico que importe la CSS y muestre una etiqueta <h2>.

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

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

      Guarde el archivo y ciérrelo. Ahora, debe importar los datos y el componente en su componente base App.

      Abra src/components/App/App/App.js:

      • nano src/components/App/App.js

      Importe los datos y el componente y, luego, realice un bucle con los datos que muestran el componente para cada elemento en la matriz:

      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;
      

      Guarde el archivo y ciérrelo. Aquí, usted utiliza el método de matriz .map() para iterar los datos. Además de añadir este bucle, también tiene un div de ajuste con una clase que usará para aplicar estilo y una etiqueta <h1> para asignar a su proyecto.

      Cuando realice el guardado, el navegador se volverá a cargar y verá una etiqueta para cada carta.

      Proyecto React en el navegador sin estilo

      A continuación, añada estilo para alinear los elementos. Abra App.css:

      • nano src/components/App/App.css

      Sustituya el contenido por lo siguiente para organizar los elementos:

      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%;
      }
      

      Esto utilizará flexbox para reorganizar los datos, de modo que los alinee. El padding da algo de espacio en la ventana del navegador. justify-content distribuirá el espacio adicional entre elementos y .wrapper h1 dará a la etiqueta Animal el ancho completo.

      Guarde el archivo y ciérrelo. Cuando lo haga, el navegador se actualizará y verá algunos datos espaciados.

      Proyecto de React en el navegador con datos espaciados

      Agregar props

      Ahora que configuró sus componentes, puede añadir su primer prop. Al hacer un bucle con sus datos, tuvo acceso a cada objeto en la matriz data y los elementos que contiene. Añadirá cada parte de los datos a un prop separado que luego usará en su componente de AnimalCard.

      Abra App.js:

      • nano src/components/App/App.js

      Añada un prop name a 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;
      

      Guarde el archivo y ciérrelo. El prop name tiene el aspecto de un atributo HTML estándar; sin embargo, en lugar de una cadena usted pasará la propiedad name del objeto animal entre llaves.

      Ahora que pasó un prop para el nuevo componente, necesita usarlo. Abra AnimalCard.js:

      • nano src/components/AnimalCard/AnimalCard.js

      Todos los props que pasa al componente se recopilan en un objeto que será el primer argumento de su función. Desestructure el objeto para extraer props individuales:

      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>
        );
      }
      

      Tenga en cuenta que no necesita desestructurar un prop para usarlo, pero que este es un método útil para gestionar los datos de ejemplo de este tutorial.

      Después de desestructurar el objeto, puede utilizar los componentes individuales de datos. En este caso, usará el título en una etiqueta <h2>, rodeando el valor con llaves para que React sepa que debe evaluarlo como JavaScript.

      También puede utilizar una propiedad en el objeto prop con notación de puntos. Como ejemplo, puede crear un elemento <h2> como este:<h2>{props.title}</h2>. La ventaja de la desestructuración es que puede recopilar props no utilizados y emplear el operador rest de objetos.

      Guarde el archivo y ciérrelo. Cuando lo haga, el navegador se volverá a cargar y verá el nombre específico de cada animal en lugar de un marcador de posición.

      Proyectos React con nombres de animales representados

      La propiedad name es una cadena, pero un prop puede ser cualquier tipo de datos que pueda pasar a una función JavaScript. Para ver esto en funcionamiento, añada el resto de los datos.

      Abra el archivo App.js:

      • nano src/components/App/App.js

      Añada un prop para cada uno de los siguientes: scientificName, size, diet y additional. Se incluyen cadenas, enteros, matrices y objetos.

      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;
      

      Debido a que creará un objeto, puede añadirlo en cualquier orden que desee. La alfabetización hace que sea más fácil examinar una lista de props, en especial en una lista más grande. También puede añadirlos en la misma línea, pero al separarlos uno en cada línea se preserva la legibilidad.

      Guarde y cierre el archivo. Abra AnimalCard.js.

      • nano src/components/AnimalCard/AnimalCard.js

      Esta vez, desestructure las props de la lista del parámetro de función y utilice los datos del componente:

      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>
        );
      }
      

      Después de extraer los datos, puede añadir scientificName y size en las etiquetas de encabezado, pero deberá convertir la matriz en una cadena para que React pueda mostrarla en la página. Puede hacerlo con join(', '), lo cual creará una lista separada con comas.

      Guarde y cierre el archivo. Cuando lo haga, el navegador se actualizará y verá los datos estructurados.

      Proyecto de React con animales con datos completos

      Puede crear una lista similar con el objeto additional y, en su lugar, añadir una función para alertar al usuario con los datos. Esto le dará la oportunidad de pasar funciones como props y, luego, utilizar datos dentro de un componente cuando invoque una función.

      Abra App.js:

      • nano src/components/App/App.js

      Cree una función llamada showAdditionalData que convertirá el objeto en una cadena y la mostrará como una alerta.

      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 función showAdditional convierte el objeto en una matriz de pares en la cual el primer elemento es la clave y el segundo el valor. Luego asigna los datos convirtiendo el par de claves en una cadena. Luego los une con un salto de línea n antes de pasar la cadena completa a la función de alerta.

      Debido a que JavaScript puede aceptar funciones como argumentos, React también puede aceptar funciones como props. Por lo tanto, puede pasar showAdditional a AnimalCard como un prop llamado showAdditional.

      Guarde y cierre el archivo. Abra AnimalCard:

      • nano src/components/AnimalCard/AnimalCard.js

      Retire la función showAdditional del objeto props y cree un <button> con un evento onClick que invoque la función con el objeto 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>
        );
      }
      

      Guarde el archivo. Cuando lo haga, el navegador se actualizará y verá un botón después de cada tarjeta. Cuando haga clic en el botón, obtendrá una alerta con los datos adicionales.

      Alerta con información

      Si intenta hacer clic en More Info para Lion, verá un error. Esto se debe a que no hay datos adicionales para el león. Verá cómo solucionarlo en el paso 3.

      Por último, añada estilo a la tarjeta de música. Añada un className de animal-wrapper al div en 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>
        )
      }
      

      Guarde y cierre el archivo. Abra AnimalCard.css:

      • nano src/components/AnimalCard/AnimalCard.css

      Añada CSS para aplicar a las tarjetas y al botón un pequeño borde y un relleno:

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

      Este CSS añadirá un pequeño borde a la tarjeta y sustituirá el estilo predeterminado de botón por un borde y relleno. cursor: pointer cambiará el cursor cuando pase el puntero sobre el botón.

      Guarde y cierre el archivo. Cuando lo haga, el navegador se actualizará y verá los datos en tarjetas individuales.

      Proyecto React con tarjetas de animales con el estilo

      En este punto, creó dos componentes personalizados. Pasó datos al segundo componente del primer componente utilizando props. Entre los props se incluyeron diferentes datos, como cadenas, enteros, matrices, objetos y funciones. En su segundo componente, empleó los props para crear un componente dinámico utilizando JSX.

      En el siguiente paso, usará un sistema de tipos llamado prop-types para especificar la estructura que su componente prevé, lo cual aportará previsibilidad en su aplicación y evitará errores.

      Paso 3: Crear props predecibles con PropTypes y defaultProps

      En este paso, agregará un sistema de tipos ligero a sus componentes con PropTypes. PropTypes funciona como otros sistemas de tipos definiendo explícitamente el tipo de datos que espera recibir para un prop determinado. También le dan la oportunidad de definir datos predeterminados en casos en que no siempre se requiere el prop. A diferencia de la mayoría de los sistemas de tipos, PropTypes es una comprobación de tiempo de ejecución. Por ello, si los props no coinciden con el tipo, el código se compilará de todas formas, pero también mostrará un error en la consola.

      Al final de este paso, sumará previsibilidad a su componente personalizado definiendo el tipo para cada prop. Esto garantizará que la siguiente que trabaje en el componente tenga una idea clara de la estructura de los datos que el componente necesitará.

      El paquete prop-types se incluye como parte de la instalación de Create React App. Para usarlo, lo único que debe hacer es importarlo a su componente.

      Abra AnimalCard.js:

      • nano src/components/AnimalCard/AnimalCard.js

      Luego importe PropTypes desde 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({
      ...
      }
      

      Añada PropTypes directamente a la función del componente. En JavaScript, las funciones son objetos; esto significa que puede añadir propiedades utilizando sintaxis de puntos. Añada los siguientes PropTypes a 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,
      }
      

      Guarde y cierre el archivo.

      Como puede ver, hay muchos PropTypes diferentes. Esta es solo una pequeña muestra; consulte la documentación oficial de React para ver los demás que puede utilizar.

      Comenzaremos con el prop name. Aquí, especificará que name debe ser una string. La propiedad scientificName es la misma. size es un number, que puede incluir números de punto flotante, como 1.5, y enteros, como 6. showAdditional is una función (func).

      diet, por otra parte, es un poco diferente. En este caso, especifica que diet será una array, pero también necesita especificar lo que esta matriz contendrá. En este caso, la matriz contendrá solo cadenas. Si desea mezclar tipos, puede utilizar otro prop llamado oneOfType, que toma una matriz de PropTypes válidos. Puede utilizar oneOfType en cualquier lugar. Por ello, si desea que size sea un número o una cadena, puede cambiar el parámetro por esto:

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

      El prop additional también es un poco más complejo. En este caso, especifica un objeto y, para una mayor claridad, indica lo que desea que contenga. Para hacerlo, se utiliza PropTypes.shape, que toma un objeto con campos adicionales que necesitarán sus propios PropTypes. En este caso, link y notes son PropTypes.string.

      Actualmente, todos los datos están bien formados y coinciden con los props. Para ver lo que sucede si los PropTypes no coinciden, abra sus datos:

      • nano src/components/App/data.js

      Cambie el tamaño a una cadena en el primer elemento:

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

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

      Guarde el archivo. Cuando lo haga, el navegador se actualizará y verá un error en la consola.

      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)

      Navegador con error de tipo

      A diferencia de otros sistemas de tipos, como TypeScript, PropTypes no le proporcionará una advertencia en el momento de la compilación y. siempre y cuando no haya errores de código, se compilará de todas formas. Esto significa que puede publicar accidentalmente código con errores de prop.

      Restablezca el tipo correcto para los datos:

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

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

      Guarde y cierre el archivo.

      Abra AnimalCard.js:

      • nano src/components/AnimalCard/AnimalCard.js

      Cada prop, a excepción de additional, tiene la propiedad isRequired. Eso significa que se necesitan. Si no incluye un prop requerido, el código se compilará de todas formas, pero verá un error de tiempo de ejecución en la consola.

      Si no se necesita un prop, puede añadir un valor predeterminado. Siempre se recomienda añadir un valor predeterminado para evitar errores de tiempo de ejecución si no se requiere un prop. Por ejemplo, en el componente AnimalCard, invoca una función con los datos additional. Si no está allí, la función intentará modificar un objeto que no existe y la aplicación fallará.

      Para evitar este problema, añada una defaultProp para 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'
        }
      }
      

      Añada los defaultProps a la función utilizando sintaxis de puntos, como lo hizo con propTypes. Luego, agregue un valor predeterminado que debe utilizar si el prop es undefined. En este caso, se hace coincidir la forma de additional, incluido un mensaje de que no hay más información.

      Guarde y cierre el archivo. Cuando lo haga, el navegador se actualizará. Después de que se actualice, haga clic en el botón More Info para Lion. No tiene un campo additional en los datos; por lo tanto, el prop es undefined. Sin embargo, AnimalCard hará una sustitución en el prop predeterminado.

      Navegador con el mensaje predeterminado para la alerta

      Ahora, sus props estarán bien documentados y serán necesarios o tendrán un valor por defecto para garantizar la previsibilidad del código. Esto ayudará a los futuros desarrolladores (incluido usted mismo) a determinar los props que un componente necesita. Esto hará que sea más fácil intercambiar y reutilizar sus componentes proporcionando información completa sobre cómo estos usarán los datos que reciben.

      Conclusión

      En este tutorial, creó varios componentes que utilizan props para mostrar la información de un elemento principal. Los props le ofrecen la flexibilidad necesaria para comenzar a desglosar los componentes más grandes en piezas más pequeñas y con mayor concentración. Ahora que sus datos ya no están acoplados estrechamente con la información de su visualización, podrá tomar decisiones sobre cómo segmentar su aplicación.

      Los props son una herramienta crucial para crear aplicaciones complejas y dan la oportunidad de crear componentes que pueden adaptarse a los datos que reciben. Con PropTypes, crea componentes predecibles y legibles que permitirán a un equipo reutilizar el trabajo de los demás para crear una base de código flexible y estable. Si desea acceder a más tutoriales de React, consulte nuestra página temática de React o regrese a la página de la serie sobre cómo desarrollar código con React.js.



      Source link

      Como personalizar os componentes React com props


      O autor selecionou a Creative Commons para receber uma doação como parte do programa Write for DOnations.

      Introdução

      Neste tutorial você criará componentes personalizados passando props (que significa propriedades) aos seus componentes. Props são argumentos que você fornece a um elemento JSX. Elas se parecem com os props padrão do HTML, mas não são pré-definidos e podem ter diferentes tipos de dados JavaScript, incluindo números, strings, funções, matrizes e até mesmo outros componentes React. Seus componentes personalizados utilizam props para exibir dados ou utilizá-los para fazer os componentes interagirem. Os props são parte fundamental da criação de componentes adaptáveis para situações diferentes. Aprender como usá-los dará a você as ferramentas necessárias para desenvolver componentes personalizados para lidar com situações únicas.

      Após adicionar os props aos componentes, você utilizará o PropTypes para definir o tipo de dados que você espera que um componente receba. O PropTypes é um sistema de tipos simples que verifica se os dados correspondem aos tipos esperados no ambiente de execução. Ele serve como uma documentação e verificador de erros que ajudará você a manter seu aplicativo previsível à medida que ele for escalonado.

      Ao final deste tutorial, você utilizará uma variedade de props para desenvolver um aplicativo pequeno que receberá uma matriz de dados de animais. Ela mostrará informações como nome, nome científico, tamanho, dieta e outras informações.

      Nota: o primeiro passo define um projeto em branco no qual você desenvolverá o exercício do tutorial. Se você já tiver um projeto de trabalho e deseja ir diretamente ao trabalho com os props, vá para o Passo 2.

      Pré-requisitos

      Passo 1 — Criando um projeto vazio

      Neste passo, você criará um novo projeto utilizando o Create React App. Em seguida, você excluirá o projeto de exemplo e os arquivos relacionados que foram instalados durante a inicialização dele. Por fim, você criará uma estrutura de arquivos simples para organizar seus componentes.

      Para começar, crie um novo projeto. Em sua linha de comando, execute o script a seguir para instalar um novo projeto usando o create-react-app:

      • npx create-react-app prop-tutorial

      Após o projeto ser finalizado, vá para o diretório:

      Em uma nova guia ou janela do terminal, inicie o projeto usando o script start do Create React App. O navegador irá atualizar automaticamente com as alterações. Dessa forma, deixe este script em execução durante todo o tempo em que você estiver trabalhando:

      Você receberá um servidor local em execução. Se o projeto não abriu na janela de um navegador, você pode abri-lo indo para http://localhost:3000/. Se o estiver executando em um servidor remoto, o endereço será http://your_domain:3000.

      Seu navegador carregará com um aplicativo simples do React, que vem incluído como parte do Create React App:

      Projeto modelo do React

      Você desenvolverá um conjunto completamente novo de componentes personalizados. Você começará seu projeto removendo um pouco do código boilerplate para que você possa ter um projeto vazio.

      Para iniciar, abra o src/App.js em um editor de texto. Esse é o componente raiz que é injetado na página. Todos os componentes iniciarão a partir daqui. Saiba mais sobre o App.js em Como configurar um projeto React com o Create React App.

      Abra o src/App.js com o seguinte comando:

      Você verá um arquivo como este:

      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;
      

      Exclua a linha import logo from './logo.svg';. Em seguida, substitua tudo na instrução return para retornar um conjunto de tags vazias: <></>. Isso dará a você uma página de validação que não retorna nada. O código final ficará parecido com este:

      prop-tutorial/src/App.js

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

      Salve e saia do editor de texto.

      Por fim, exclua o logo. Você não o usará neste seu aplicativo e é aconselhável remover arquivos não utilizados durante o trabalho. Isso evitará confusões futuras.

      Na janela do terminal, digite o seguinte comando:

      Se você olhar em seu navegador, verá uma tela vazia.

      tela vazia no chrome

      Com o projeto de exemplo do Create React App limpo, crie uma estrutura de arquivos simples. Isso ajudará você a manter os componentes isolados e independentes.

      Crie um diretório chamado components no diretório src. Ele terá todos os seus componentes personalizados.

      Cada componente terá o próprio diretório para armazenar o arquivo de componente com os estilos, imagens (se houver) e testes.

      Crie um diretório para o App:

      Mova todos os arquivos App para esse diretório. Use o curinga * para selecionar quaisquer arquivos que comecem com App., independentemente da extensão. Depois, utilize o comando mv para colocá-los no novo diretório.

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

      Por fim atualize o caminho de importação relativo em index.js, que é o componente raiz que inicializa todo o processo.

      A instrução de importação precisa apontar para o arquivo Apps.js no diretório App. Portanto, faça a seguinte alteração destacada:

      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();
      

      Salve e saia do arquivo.

      Agora que o projeto está configurado, crie o primeiro componente.

      Neste passo, você criará um componente que será modificado com base nas informações de entrada, chamadas props. Os props são argumentos que você passa para uma função ou classe. Como seus componentes são transformados em objetos semelhantes aos HTML pelo JSX, você passará os props como se fossem atributos do HTML. Diferente dos elementos HTML, você pode passar vários tipos de dados diferentes: strings, matrizes. objetos e até mesmo funções.

      Aqui, você criará um componente que exibirá as informações de animais. Esse componente terá o nome e nome científico do animal como strings, o tamanho como um número inteiro, a dieta será uma matriz de strings e as informações adicionais serão um objeto. Você passará as informações para o novo componente como props e as consumirá no componente.

      Ao final deste passo, você terá um componente que consumirá diferentes props. Você também reutilizará o componente para exibir uma matriz de dados usando um componente comum.

      Adicionando dados

      Primeiro, serão necessários dados de exemplo. Crie um arquivo no diretório src/App chamado data.

      • touch src/components/App/data.js

      Abra o novo arquivo em seu editor de texto:

      • nano src/components/App/data.js

      Em seguida, adicione uma matriz de objetos que será usada como exemplo:

      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'
          }
        }
      ]
      

      A matriz de objetos contém uma variedade de dados e dará a você a oportunidade de testar uma variedade de props. Cada objeto é um animal separado com o nome dele, o nome científico, o tamanho, a dieta e um campo opcional chamado additional que contém links ou anotações. Neste código você também exportou a matriz como default.

      Salve e saia do arquivo.

      Criando componentes

      Em seguida, crie um componente de espaço reservado chamado AnimalCard. Este componente eventualmente utilizará props e exibirá os dados.

      Primeiro, crie um diretório em src/components chamado AnimalCard. Em seguida, use o comando touch para criar um arquivo chamado src/components/AnimalCard/AnimalCard.js e um arquivo CSS chamado src/components/AnimalCard/AnimalCard.css.

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

      Abra o AnimalCard.js no seu editor de texto:

      • nano src/components/AnimalCard/AnimalCard.js

      Adicione um componente básico que importa o CSS e retorna uma tag <h2>.

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

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

      Salve e saia do arquivo. Agora, é necessário que você importe os dados e os componentes em seu componente base App.

      Abra o src/components/App/App.js:

      • nano src/components/App/App.js

      Importe os dados e os componentes. Em seguida, faça um loop com os dados para retornar os componentes para cada item na matriz:

      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;
      

      Salve e saia do arquivo. Aqui,utilize o método de matriz .map() para iterar os dados. Além da adição deste loop, você também terá uma div de quebra automática com uma classe que você utilizará para aplicação de estilo e uma tag <h1> para rotular seu projeto.

      Quando você salvar, o navegador será recarregado e você verá um rótulo para cada cartão.

      Projeto React no navegador sem estilo

      Em seguida, vamos aplicar o estilo para alinhar os itens. Abra o App.css:

      • nano src/components/App/App.css

      Para organizar os elementos, substitua o conteúdo pelo seguinte:

      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%;
      }
      

      Isso utilizará o flexbox para reorganizar os dados de modo que fiquem alinhados. O padding coloca um pouco de espaço na janela do navegador. O justify-content espalhará o espaço extra entre os elementos e o .wrapper h1 fornecerá a largura total do rótulo Animal.

      Salve e saia do arquivo. Quando fizer isso, o navegador será recarregado e você verá alguns dados espaçados.

      Projeto React no navegador com dados espaçados

      Adicionando props

      Com seus componentes configurados, adicione seu primeiro prop. Ao fazer o loop com os dados, você terá acesso a cada objeto na matriz data e a cada item que o objeto tem. Você adicionará cada um dos dados em um prop separado que você utilizará depois em seu componente AnimalCard.

      Abra App.js:

      • nano src/components/App/App.js

      Adicione um prop de name para 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;
      

      Salve e saia do arquivo. O prop name se parece com um atribuito HTML padrão, mas em vez de uma string, você passará a propriedade name do objeto animal entre chaves.

      Agora que você passou um prop para o novo componente, você precisa usá-lo. Abra o AnimalCard.js:

      • nano src/components/AnimalCard/AnimalCard.js

      Todos os props que você passa para o componente são coletados em um objeto que será o primeiro argumento da função. Desestruture o objeto para extrair os props individuais:

      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>
        );
      }
      

      Observe que não é necessário desestruturar um prop para usá-lo. Esse é um método útil para lidar os com dados de exemplo neste tutorial.

      Após desestruturar o objeto, você pode usar os dados individuais. Neste caso, você utilizará o título em uma tag <h2>, colocando o valor entre chaves para que o React saiba avaliá-lo como JavaScript.

      Você também pode usar uma propriedade no objeto prop usando a notação de ponto. Por exemplo, crie um elemento <h2> assim: <h2>{props.title}</h2>. A vantagem da desestruturação é que você coleta os props não utilizados e usa o objeto operador rest.

      Salve e saia do arquivo. Quando fizer isso, o navegador será recarregado e você verá o nome específico para cada animal em vez de um espaço reservado.

      Projetos do React com nomes de animais renderizados

      A propriedade name é uma string, mas os props podem ser de qualquer tipo de dados que você poderia passar para uma função JavaScript. Para ver isto em funcionamento, adicione o resto dos dados.

      Abra o arquivo App.js:

      • nano src/components/App/App.js

      Adicione um prop para cada um dos seguintes: scientificName, size, diet e additional. Eles possuem strings, inteiros, matrizes e objetos.

      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;
      

      Como está criando um objeto, você pode adicioná-los em qualquer ordem que quiser. A ordem alfabética facilita a busca em uma lista de props, principalmente em uma lista muito grande. Você também pode colocá-los na mesma linha. No entanto, separá-los um por linha facilita a leitura.

      Salve e feche o arquivo. Abra o AnimalCard.js.

      • nano src/components/AnimalCard/AnimalCard.js

      Desta vez, desestruture os props na lista de parâmetros das funções e use os dados no componente:

      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>
        );
      }
      

      Após retirar os dados, adicione o scientificName e o size em tags de cabeçalho. Será necessário converter a matriz em uma string para que o React possa exibi-la na página. Faça isso com o join(', '), que criará uma lista separada por vírgula.

      Salve e feche o arquivo. Quando fizer isso, o navegador recarregará e você verá os dados estruturados.

      Projeto React com os animais com os dados completos

      Você poderia criar uma lista parecida com o objeto additional, mas, em vez disso, adicione uma função para alertar o usuário com os dados. Isso dará a você a chance de passar funções como props e utilizar os dados dentro de um componente ao chamar uma função.

      Abra App.js:

      • nano src/components/App/App.js

      Crie uma função chamada showAdditionalData, que converte o objeto em uma string e a exibirá como um alerta.

      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;
      

      A função showAdditional converte o objeto para uma matriz de pares onde o primeiro item é a chave e o segundo é o valor. Em seguida, ele mapeia os dados convertendo o par de chaves para uma string. Depois, ele as junta com uma quebra de linha (n) antes de passar a string completa para a função de alerta.

      Como o JavaScript pode aceitar funções como argumentos, o React também aceita funções como props. Por este motivo, você pode passar o showAdditional para o AnimalCard como um prop chamado showAdditional.

      Salve e feche o arquivo. Abra o AnimalCard:

      • nano src/components/AnimalCard/AnimalCard.js

      Traga a função showAdditional do objeto props. Em seguida, crie um <button> com um evento onClick que chama a função com o objeto 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>
        );
      }
      

      Salve o arquivo. Quando fizer isso, o navegador será recarregado e você verá um botão após cada cartão. Quando você clicar no botão, receberá um alerta com os dados adicionais.

      Alerta com informações

      Se você tentar clicar em More Info para o Lion, receberá um erro. Isso acontece porque não existem dados adicionais para o leão. Você verá como corrigir isso no Passo 3.

      Finalmente, adicione um pouco de estilo ao cartão de música. Adicione um className de animal-wrapper ao div em 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>
        )
      }
      

      Salve e feche o arquivo. Abra o AnimalCard.css:

      • nano src/components/AnimalCard/AnimalCard.css

      Adicione o CSS para dar aos cartões e ao botão uma borda e um preenchimento:

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

      Este CSS adicionará uma borda leve ao cartão e substituirá o estilo padrão do botão para um com borda e preenchimento. O cursor: pointer alterará o cursor quando você passar o mouse por cima do botão.

      Salve e feche o arquivo. Quando fizer isso, o navegador será recarregado e você verá os dados em cartões individuais.

      Projeto React com os cartões de animais com estilos aplicados

      Neste ponto, você criou dois componentes personalizados. Você passou dados para o segundo componente a partir do primeiro componente usando os props. Os props incluíram uma variedade de dados, como strings, números inteiros, matrizes, objetos e funções. Em seu segundo componente, você utilizou os props para criar um componente dinâmico usando o JSX.

      No próximo passo, você utilizará um sistema de tipos chamado de prop-types para especificar a estrutura que o componente espera ver. Este sistema criará uma previsibilidade em seu aplicativo e evitará bugs.

      Neste passo, você adicionará um sistema leve de tipos aos seus componentes com o PropTypes. O PropTypes age da mesma forma que outros sistemas de tipos, definindo explicitamente o tipo de dados que você espera receber de um certo prop. Ele também dá a você a chance de definir dados padronizados nos casos onde o prop não é muito necessário. Ao contrário da maioria dos sistemas de tipos, o PropTypes é um verificador do ambiente de execução. Desta forma, se os props não corresponderem ao tipo, o código ainda compilará, porém, ele exibirá um erro de console.

      Ao final deste passo, você adicionará a previsibilidade ao seu componente personalizado, definindo o tipo para cada prop. Isso garantirá que a próxima pessoa que trabalhar no componente tenha uma ideia clara sobre a estrutura dos dados de que o componente precisará.

      O pacote prop-types está incluído como parte da instalação do Create React App. Por este motivo, tudo que você precisa fazer é importá-lo em seu componente.

      Abra o AnimalCard.js:

      • nano src/components/AnimalCard/AnimalCard.js

      Em seguida, importe o PropTypes do 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({
      ...
      }
      

      Adicione o PropTypes diretamente à função do componente. Em JavaScript, as funções são objetos. Isso significa que você pode adicionar propriedades usando a sintaxe de ponto. Adicione os seguintes PropTypes para o 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,
      }
      

      Salve e feche o arquivo.

      Como você pode ver, existem vários tipos diferentes de PropTypes. Esta é apenas uma pequena amostra; consulte a documentação oficial do React para ver os outros PropTypes que você pode usar.

      Vamos começar pelo prop name. Aqui, você está especificando que name deve ser do tipo string. A propriedade scientificName é a mesma coisa. O size é um número que pode incluir floats como 1.5 e inteiros como 6. O showAdditional é uma função (func).

      O diet, por outro lado, é um pouco diferente. Neste caso, você está especificando que o diet será uma array, mas você também precisa especificar o que essa matriz conterá. Neste caso, a matriz conterá apenas strings. Se quiser misturar os tipos, utilize outro prop chamado de oneOfType, que recebe uma matriz de PropTypes válidos. Você pode utilizar o oneOfType em qualquer lugar. Se quiser que o size seja tanto um número quanto uma string, modifique-o para isto:

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

      O prop additional também é um pouco mais complexo. Neste caso, você está especificando um objeto, mas, para ficar um pouco mais claro, você está declarando o que quer que o objeto contenha. Para fazer isso, utilize o PropTypes.shape, que recebe um objeto com campos adicionais que precisarão de seus próprios PropTypes. Neste caso, o link e o notes são ambos PropTypes.string.

      No momento, todos os dados estão bem estruturados e correspondem aos props. Para ver o que acontece se o PropTypes não for correspondido, abra seus dados:

      • nano src/components/App/data.js

      Modifique o tamanho para uma string no primeiro item:

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

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

      Salve o arquivo. Quando fizer isso, o navegador recarregará e você verá um erro no 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)

      Navegador com erro de tipo

      Ao contrário de outros sistemas de tipos como o TypeScript, o PropTypes não dará um aviso a você no momento da compilação. Enquanto não houver erros, ele ainda compilará. Isso significa que você pode publicar um código com erros de prop acidentalmente.

      Modifique os dados de volta para o tipo correto:

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

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

      Salve e feche o arquivo.

      Abra o AnimalCard.js:

      • nano src/components/AnimalCard/AnimalCard.js

      Todo prop (com exceção do additional) possui a propriedade isRequired. Isso significa que eles são necessários. Se você não incluir um prop necessário, o código ainda compilará, mas você verá um erro do ambiente de execução no console.

      Se um prop não for necessário, você pode adicionar um valor padrão. Uma boa medida é sempre adicionar um valor padrão para evitar erros do ambiente de execução se um prop não for necessário. Por exemplo, no componente AnimalCard você está chamando uma função com os dados de additional. Se os dados não estiverem lá, a função tentará modificar um objeto que não existe e o aplicativo falhará.

      Para evitar este problema, adicione um defaultProp para o 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'
        }
      }
      

      Adicione o defaultProps à função usando a sintaxe de ponto da mesma forma que você fez com o propTypes. Em seguida, adicione um valor padrão que o componente deve usar se o prop for undefined. Neste caso, você está correspondendo o formato do additional incluindo uma mensagem de que não há informações adicionais.

      Salve e feche o arquivo. Quando fizer isso, o navegador recarregará. Após ele recarregar, clique no botão More Info para o Lion. Ele não possui um campo additional nos dados. Por este motivo, o prop está undefined. Porém, o AnimalCard será substituído no prop padrão.

      Navegador com a mensagem padrão no alerta

      Agora seus props estão bem documentados e são necessários ou possuem um padrão para garantir um código previsível. Isso ajudará que futuros desenvolvedores (incluindo você) entendam quais props de que um componente precisa. Ele facilitará a troca e a reutilização dos seus componentes, fornecendo informações completas sobre como o componente utilizará os dados que ele está recebendo.

      Conclusão

      Neste tutorial, você criou vários componentes que usam os props para exibir informações de um pai. Os props fornecem a flexibilidade que você precisa para começar a separar componentes maiores em partes menores e mais focadas. Agora que você não possui mais seus dados fortemente acoplados às informações de exibição, você pode fazer escolhas sobre como segmentar seu aplicativo.

      Os props são ferramentas importantes no desenvolvimento de aplicativos complexos. Eles dão a oportunidade de criar componentes que se adaptam aos dados que recebem. Com o PropTypes, você está criando componentes previsíveis e legíveis que darão a uma equipe a habilidade de reutilizar o trabalho uns dos outros para, desta maneira, criarem uma base de código flexível e estável. Se você quiser analisar mais tutoriais do React, dê uma olhada em nossa página sobre o React ou retorne à página da série Como Programar em React.js.



      Source link