Il s'agit d'une version statique de l'intranet d'A. Jonquet, certaines fonctionnalités sont donc potentiellement non fonctionnelles.
Rejoindre la version dynamique 🔒
r410
Navigation

Une application de partage de signets en React - partie 3

Ce TP est le troisième d'une série où vous allez créer la base d'une application permettant d'afficher et de gérer une liste de signets.

Il se focalisera sur la simplification de la gestion des données des composants à l'aide des contextes React.

Remarque importante

Les notes des TP seront obtenues à partir de vos dépôts Git, vous devrez donc prendre grand soin de la qualité de ces dépôts et de leurs « commits ».

De manière similaire, les descriptions de vos « commits » devront être claires et informatives, afin de permettre l'évaluation de la progression de votre travail.

Objectifs de la séance

  • Utilisation d'une API de données
  • Gestion de requêtes AJAX authentifiées
  • Utilisation des contextes React
  • Gestion de données asynchrones

Requête permettant d'obtenir l'utilisateur courant

Pour authentifier l'utilisateur de l'application auprès de l'API vous allez utiliser les cookies de session. Et pour obtenir les informations de l'utilisateur courant, vous utiliserez la ressource « /me » de l'API.

Vous ajouterez une nouvelle fonction getMe() au module « services/api/bookmarks.js » qui retournera une promesse des données de l'utilisateur si celui-ci est connecté et une promesse de null sinon. La requête obtient un code de réponse HTTP 401 si l'utilisateur n'est pas connecté.

Pour informer le navigateur qu'il doit transmettre le cookie de session lors de la requête AJAX, vous utiliserez l'option credentials de fetch avec la valeur "include".

Vous en profiterez pour ajouter deux nouvelles fonctions, exportées nommées :

L'URL de connexion de l'API peut être complétée avec un paramètre d'URL redirect permettant à l'utilisateur d'être redirigé vers l'application après son authentification. Le paramètre doit recevoir l'URL vers laquelle réaliser la redirection. Pour obtenir l'URL courante du navigateur, vous pouvez utiliser la propriété location de l'objet window.

Vous penserez à protéger la valeur du paramètre à l'aide de la fonction encodeURIComponent.

Travail à réaliser
  • Creation de la fonction getMe().
  • Creation de la fonction loginUrl().
  • Creation de la fonction logoutUrl().

Ajout d'un contexte pour la gestion de l'utilisateur

L'application va devoir stocker les informations de l'utilisateur connecté et les rendre disponibles à l'ensemble de l'application.

Pour éviter de transmettre cette information au travers des composants de l'application en la transmettant sous forme de nombreuses propriétés de composants, ce qui deviendrait rapidement fastidieux, vous allez les stocker dans un contexte React.

Vous commencerez par créer le contexte. Dans un sous-répertoire « src/contexts/user » vous ajouterez un nouveau script « index.js » dont le rôle sera d'exporter par défaut le contexte de l'utilisateur courant.

Vous ajouterez aussi un script « Provider.jsx » au sous-répertoire « src/contexts/user » dont le rôle sera d'exporter par défaut le fournisseur (« provider ») de contexte pour l'utilisateur courant. Pour ce faire, vous exporterez un composant React d'ordre supérieur dont le rendu sera composé du fournisseur (« provider ») de contexte de l'utilisateur, encapsulant les fils du composant.

Le composant Provider comportera une variable d'état userData qui stockera les données de l'utilisateur. Cette variable pourra être dans l'un de ces 3 états :

  • En synchronisation, les informations de l'utilisateur sont incertaines, la variable vaut undefined,
  • L'utilisateur est connecté, la variable contient les données émises par l'API web.
  • Aucun utilisateur n'est connecté, la variable vaut null.

La valeur par défaut de userData sera donc undefined jusqu'à ce que le composant obtienne une réponse HTTP de la fonction getMe, émise depuis un hook useEffect.

La valeur du contexte initialisée par le fournisseur (« provider ») de contexte contiendra la variable d'état userData.

Vous rendrez le contexte de l'utilisateur accessible à tous les composants de l'application en utilisant le composant fournissant le contexte dans le fichier « App.jsx ». Vous devrez constater dans votre console de développement l'exécution de la requête AJAX vers getMe.

Travail à réaliser
  • Création du contexte utilisateur.
  • Création du fournisseur du contexte de l'utilisateur.

Composant d'en-tête

Pour illustrer l'absence de propagation de propriété de composant, vous allez créer un composant d'en-tête dont le seul rôle sera d'afficher le titre de l'application et de contenir le bouton de gestion de l'utilisateur.

Le composant recevra une propriété de composant title contenant le titre de l'application.

Vous utiliserez ensuite ce composant dans le composant App afin qu'il apparaisse dans votre application, et vous devriez de nouveau obtenir une application fonctionnelle.

Travail à réaliser
  • Création du composant Header.
  • Utilisation du composant Header dans le composant App.

Création du bouton de gestion de l'utilisateur

Maintenant que les données de l'utilisateur sont disponibles, vous allez créer un nouveau composant UserButton permettant à l'utilisateur de savoir s'il est connecté ou non et de se connecter ou déconnecter en fonction.

Vous ajouterez le composant React UserButton à votre projet et il utilisera le contexte de l'utilisateur pour obtenir ses données, en utilisant le hook useContext.

Selon la valeur des données de l'utilisateur, le composant affichera :

  • un indicateur de chargement si les données sont undefined.
  • un bouton de connexion, avec une icône Font Awesome (key par exemple), si les données sont null.
  • un bouton de déconnexion avec l'avatar de l'utilisateur si les données sont valides.

L'indicateur de chargement pourra réutiliser votre composant Loading créé dans le TP précédent, éventuelement en lui ajoutant une propriété restreignant son affichage à une icône.

Le bouton de connexion sera un simple lien vers l'URL de connexion de l'API web (« /login »).

Le bouton de déconnexion sera aussi un simple lien vers l'URL de connexion de l'API web (« /logout »).

Vous ajouterez un bouton de gestion de l'utilisateur dans le composant Header de votre application, avec le CSS que vous estimerez nécessaire.

Vous constaterez que le composant accède aux données de l'utilisateur sans qu'aucune propriété de composant ne lui soit transmise. Le prix à payer pour cette simplicité d'utilisation est un couplage fort entre le composant et le contexte. En effet ce composant ne peut fonctionner que si le context de l'utilisateur courant à été défini dans un de ses ancêtres.

Remarque importante

Firefox semble être parfois excessivement prudent pour la gestion des cookies inter-site. Pour que l'authentification fonctionne convenablement, vous devrez peut-être mettre une exception de sécurité pour l'API, afin qu'il accepte de transmettre le cookie de la session où vous étiez authentifié. Dans les paramètres de Firefox, dans la section « Vie privée et sécurité », vous pourrez ajouter une exception pour l'API en utilisant l'URL https://iut-rcc-infoapi.univ-reims.fr :

Configuration de l'exception de gestion de cookie Configuration de l'exception de gestion de cookie
Travail à réaliser
  • Création du composant UserButton.
  • Ajout d'un composant UserButton dans l'en-tête de l'application.

Modification de la valeur du contexte - un contexte de couleur

Vous venez de voir comment obtenir des données depuis le contexte, mais ces données sont initialisées et modifiées dans le fournisseur de contexte. Vous allez maintenant voir comment permettre à l'utilisateur de modifier les données depuis un composant consommant le contexte.

Vous commencerez par créer un nouveau contexte React permettant de gérer la couleur du titre de l'application.

Le fournisseur du contexte exposera un object JavaScript contenant une variable d'état stockant la couleur du titre de l'application ainsi qu'une fonction permettant de générer une nouvelle couleur aléatoire dans la variable d'état.

Vous ajouterez ce fournisseur de contexte au composant App.

Vous utiliserez la valeur exposée par le contexte pour définir la couleur du texte du titre de l'application en utilisant la propriété HTML style.

Travail à réaliser
  • Ajout d'un contexte de gestion de la couleur du titre.
  • Utilisation du contexte de couleur dans le composant Header.

Création d'un pied de page

Vous allez ensuite ajouter un nouveau composant Footer représentant le pied de page de l'application. Sa fonction sera d'afficher l'utilisateur courant lorsqu'il est connecté.

Vous ajouterez aussi au pied de page de l'application un bouton qui sera le support du clic de la souris et permettra de générer une nouvelle couleur aléatoire pour le titre de l'application.

Une fois le composant Footer ajouté à votre application, vous devriez voir la couleur du titre de l'application changer lors de chaque clic de la souris sur le bouton de changement de palette.

Travail à réaliser
  • Création du composant Footer.
  • Utilisation du composant Footer dans le composant App.

Mutualisation des « providers »

L'imbrication de nombreux fournisseurs de contexte dans le composant App rend le composant peu lisible. Vous allez créer un composant Providers qui recevra sous forme de propriété React (props) un tableau de fournisseur de contexte et qui imbriquera ces fournisseurs de contexte autour de ces enfants.

L'imbrication sera réalisée en ajoutant progressivement les « providers » autour de la propriété React children à l'aide d'une boucle ou de la méthode reduce.

Travail à réaliser
  • Création du composant Providers.
  • Utilisation de Providers dans le composant App.

La liste des notes d'un utilisateur

Vous ajouterez une liste de notes au détail d'un utilisateur, si celui-ci est connecté. Dans cette optique vous devrez ajouter un nouveau service permettant d'obtenir la liste des notes d'un utilisateur.

Pour détecter si l'utilisateur est connecté, vous pouvez utiliser les données du contexte de l'utilisateur, mais plus simplement, vous pouvez réaliser la requête et n'afficher le résultat que si vous obtenez une réponse positive de l'API.

Travail à réaliser
  • Création du service getUserRatings.
  • Création des composants RatingItem et RatingsList.
  • Ajout de la liste des notes au détail d'un utilisateur.
A. Jonquet DUT-INFO/REIMS