5. Ajouter une icône de chargement

Pour le moment, notre application fonctionne parfaitement. Et pourtant comme d’habitude, je pense qu’il manque quelque chose et que l’on peut faire mieux. 😏

En fait, je vois un problème, c’est que notre API Rest renvoie des données quasiment instantanément. Il n’y a aucun délai entre la requête que l’on envoie et la réponse reçue. Or c’est rarement le cas dans la vraie vie !

Je vous propose donc de simuler un délai pour les réponses de nos requêtes, et voir comment notre application se comporte. Pour cela, rien de plus simple, car la librairie json-server est plutôt bien faites, et dispose d’une option nommée … delay ! Modifiez la commande dans votre fichier package.json à la ligne 6 :

{
  "name": "react-pokemons-app",
  ...
  "scripts": {
    "start": "react-scripts start",
    "start:api": "json-server --watch src/models/db.json --port=3001 --delay=500",
    "build": "react-scripts build"
  },
  ...
}

L’option delay que nous avons ajouté prend en paramètre un nombre de millisecondes permettant d’ajouter un délai de réponse à nos requêtes HTTP. D’ailleurs, je vous invites à couper la commande actuel faisant tourner votre API Rest (Ctrl + C), et relancer la commande :

npm run start:api

Avez-vous remarqué qu’il y a un petit délai de chargement entre les pages ? Depuis que nous avons ajouté un délai, notre application est un peu plus lente !

Rassurez-vous, c’est un comportement parfaitement « normal ». Toute les applications prennent plus ou moins de temps pour récupérer les données depuis une API Rest distante, et nous devons attendre une réponse avant de pouvoir afficher les résultats. Cependant, nous pourrions rendre ce temps d’attente plus agréable pour l’utilisateur en ajoutant une icône de chargement. 👍

On ajoute une icône de chargement pour l’utilisateur.

L’icône de chargement que nous allons utiliser est un élément fourni par la librairie de style Materialize.

Pour cela, je vous propose de créer un nouveau composant pour représenter l’icône de chargement. Créer donc un fichier loader.tsx dans le dossier components :

import React, { FunctionComponent } from 'react';

const Loader: FunctionComponent = () => {
 
  return (
    <div className="preloader-wrapper big active"> 
      <div className="spinner-layer spinner-blue"> 
        <div className="circle-clipper left"> 
          <div className="circle"></div> 
        </div>
        <div className="gap-patch"> 
          <div className="circle"></div> 
        </div><div className="circle-clipper right"> 
          <div className="circle"></div> 
        </div>
      </div> 
   </div> 
  );
}
 
export default Loader;

Ce composant n’a pas de logique propre, il se contente d’afficher une petite icône circulaire. Il peut ensuite être injecté à tel ou tel endroit dans l’application, selon vos besoins. Nous allons l’afficher sur la page de détail d’un Pokémon, pendant que nous attendons de récupérer les données depuis l’API Rest.

Effectuez les modifications suivantes dans le template pokemon-detail.tsx :

// Les importations et les types.
 
const PokemonsDetail: FunctionComponent<RouteComponentProps<Params>> = ({ match }) => {
  // ...
   
  return (
    <div>
      { pokemon ? (
        <div className="row">
          ...
        </div>
      ) : (
        <h4 className="center"><Loader /></h4>
      )}
    </div>
  );
}
 
export default PokemonsDetail;

On remplace notre message précédent « Aucun pokémon à afficher » par cette nouvelle icône de chargement.

On duplique ensuite cette opération dans le composant pokemon-edit.tsx :

// Les importations et les types.
 
const PokemonsEdit: FunctionComponent<RouteComponentProps<Params>> = ({ match }) => {
  // ...
   
  return (
    <div>
      { pokemon ? (
        <div className="row">
          ...
        </div>
      ) : (
        <h4 className="center"><Loader /></h4>
      )}
    </div>
  );
}
 
export default PokemonsEdit;

Et voilà, c’est tout bon !

Vous pouvez redémarrer l’application et profiter des icônes de chargement, comme sur un vrai site ! 😎