Article original : How to Build a High-Performance Tab Component in React

Les onglets sont bien plus que de simples éléments d'interface utilisateur – ils constituent l'épine dorsale de la navigation utilisateur et de l'organisation du contenu dans de nombreuses applications. Dans React, créer un composant à onglets à la fois efficace et réactif n'est pas seulement une amélioration, c'est une nécessité.

Cet article plonge en profondeur dans la construction d'un composant d'onglets React qui excelle en performance et en expérience utilisateur. Nous aborderons comment créer, optimiser et animer des onglets de manière efficace.

Vous apprendrez également à utiliser le Profiler dans les outils de développement pour identifier et réduire les re-rendus inutiles, et comment appliquer Framer Motion pour élever vos onglets au-delà du fonctionnel pour les rendre délicieux.

Prérequis

  • Fondamentaux de HTML et CSS
  • Fondamentaux de JavaScript ES6
  • Fondamentaux de React et Framer Motion.

Ce que nous allons couvrir :

  1. Comment configurer un environnement
  2. Le cœur du composant Tab
  3. Comment construire le composant Tab
    Comment construire l'UI
    Comment implémenter la fonctionnalité Tab
    Comment optimiser le composant Tab
    Comment animer le composant
  4. Autres méthodes pour affiner les performances
  5. Conclusion

Comment configurer un environnement

Pour construire un composant d'onglets React haute performance, la première chose à faire est de configurer un environnement de développement propre.

Avant de plonger dans la création de composants React, assurez-vous d'installer Node.js sur votre ordinateur. Cela prépare le terrain pour un processus de développement efficace.

Comment créer un projet React

Après avoir installé Node.js, utilisez Vite (un outil de construction moderne pour les projets React) pour créer un nouveau projet React. Dans votre terminal local, exécutez la commande :

npm create vite@latest

Sélectionnez React comme framework et votre variante préférée.

Image Configuration de l'application React

Ensuite, pour installer les packages nécessaires, exécutez npm install et ouvrez-le dans votre IDE.

Pour l'instant, votre application devrait ressembler à ceci :

Image Configuration de l'application React terminée

Enfin, démarrez le serveur de développement en exécutant npm run dev et allez sur le port donné.

Le cœur du composant Tab

Imaginez le composant d'onglets comme un standard téléphonique intelligent, vous guidant en douceur à travers différentes sections de contenu – similaire au fait de changer de chaînes de télévision ou de syntoniser des stations de radio.

Deux parties principales rendent cela possible :

  • Boutons d'onglets : Ceux-ci agissent comme des interrupteurs sélecteurs, contenant des onglets individuels prêts pour vos clics. Cliquer sur ces onglets revient à choisir différentes vues ou chaînes de contenu.
  • Panneaux d'onglets : Considérez ceux-ci comme les diffusions de contenu liées à chaque onglet. Seul le contenu connecté à l'onglet actif est sous les projecteurs, comme syntoniser une chaîne spécifique pour une visualisation claire.

Comment construire le composant Tab

Cette section comprend 4 parties :

  1. Construire l'UI
  2. Implémenter la fonctionnalité des onglets
  3. Optimiser le composant d'onglets
  4. Comment animer le composant

Comment construire l'UI

Cette section comprend toutes les maquettes et le style nécessaires pour rendre votre composant sur la page. Voici un guide étape par étape du processus :

Tout d'abord, créez un tableau contenant toutes les données utilisées par votre application dans votre composant App.

import "./App.css";

function App() {
  const petData = [
    {
      animal: "Cheetah",
      fact: "Cheetahs are the fastest land animals, capable of reaching speeds up to 75 mph.",
      image: "../src/assets/6.svg",
    },
    {
      animal: "Koala",
      fact: "Koalas sleep around 20 hours a day and are known for their eucalyptus diet.",
      image: "../src/assets/3.svg",
    },
    {
      animal: "Elephant",
      fact: "Elephants have the largest brains among land animals and demonstrate remarkable intelligence.",
      image: "../src/assets/1.svg",
    },
    {
      animal: "Zebra",
      fact: "Zebras have distinctive black and white stripes that act as a natural defense against predators.",
      image: "../src/assets/7.svg",
    },
    {
      animal: "Horse",
      fact: "Horses have excellent memory and are capable of recognizing human emotions.",
      image: "../src/assets/5.svg",
    },
  ];

  return (
    <div className="main__container">
      <h1>Choose your pet</h1>
    </div>
  );
}

export default App;

Ensuite, créez deux composants TabButtons et TabContent qui contrôleront l'onglet et afficheront le contenu de l'onglet, respectivement. Ensuite, importez-les dans le composant App.

Ensuite, passez le tableau de données de votre composant d'application dans les deux composants en utilisant les props.

// Reste du composant app
return (
    <div className="main__container">
      <h1>Choose your pet</h1>
      <TabButtons

        petData={petData}
      />
      <TabContent petData={petData} />
    </div>
  );

Ensuite, parcourez les données dans les deux composants pour créer les boutons qui seront utilisés pour contrôler le composant et les données affichées par rapport à chaque onglet.

Pour le composant TabButtons :

export default function TabButtons({ petData }) {
  return (
    <div className="tab__header">
      {petData.map((item, index) => (
               <li
          className={`tab__button`}
          key={item.animal}
                 >
          {item.animal}
        </li>
      ))}
    </div>
  );
}

Le composant TabContent :

export default function TabContent({ petData}) {
  return (
    <div className="tab__container ">
      <div className="tab__content">
        {petData.map((pet) => (
          <div key={pet}>
            <img src={pet.image} alt="" />
            <p>{pet.fact}</p>
          </div>
        ))}
      </div>
    </div>
  );
}

Pour le style, utilisez ce CSS qui contient tous les styles nécessaires pour l'ensemble de l'application dans votre fichier App.css :

@import url("https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;600;700&display=swap");

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html {
  font-size: 62.5%;
}

:root {
  --text-color: #9eb25d;
  --bg-color: rgba(238, 252, 206, 0.4);
}

body {
  font-family: "Space Grotesk", sans-serif;
  height: 100dvh;
  display: grid;
  place-items: center;
}

.main__container {
  border-radius: 2rem;
  display: flex;
  margin-top: 4rem;

  flex-direction: column;
  gap: 4rem;

  align-items: center;
  font-family: "Space Grotesk", sans-serif;
  width: max-content;
  padding: 8rem;
  color: var(--text-color);
  background: var(--bg-color);
  box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.2);
}

h1 {
  font-size: 4rem;
}
.tab__header {
  display: flex;
  list-style: none;
  gap: 2rem;
}

.tab__header li {
  flex: 1;
  cursor: pointer;
  padding: 2rem;
  border: 2px solid var(--text-color);
  text-align: center;
  border-top-right-radius: 100%;
  border-top-left-radius: 100%;
  font-size: 2rem;
}

.tab__container {
  display: flex;
  flex-direction: column;
  font-size: 2rem;
  width: 80rem;
  border-radius: 2rem;
  padding: 4rem;
  box-shadow: inset -3px -3px 3px rgba(0, 0, 0, 0.2),
    inset 3px 3px 3px rgba(0, 0, 0, 0.2);
  gap: 2rem;
}

.tab__content {
  padding: 2rem;
  min-height: 25rem;
  border: 2px solid var(--text-color);
  display: flex;
  justify-content: space-between;
  flex-direction: column;
  align-items: center;
  gap: 4rem;
  background: #fff;
  border-radius: 2rem;
}

.tab__content img {
  max-width: 31rem;
  max-height: 20rem;
  width: 100%;
}

.tab__content p {
  text-align: center;
}

.active {
  background: var(--text-color);

  color: #fff;
  font-weight: 600;
}

@media screen and (max-width: 1000px) {
  .main__container {
    gap: 2rem;
    padding: 1rem;
    width: 95%;
    margin: 5rem auto;
  }

  h1 {
    font-size: 3rem;
  }

  .tab__header {
    flex-wrap: wrap;
  }

  .tab__content {
    gap: 2rem;
    min-height: 35rem;
  }
  .tab__header li {
    font-size: 1.6rem;
  }

  .tab__container {
    width: 100%;
    padding: 2rem;
  }

  .tab__content img {
    max-width: 150px;
  }

  .tab__content p {
    font-size: 1.6rem;
  }
}

Ou vous pouvez alternativement aller ici pour les styles : Fichier CSS

Pour l'instant, votre page devrait ressembler à ceci :

Image Page initiale après avoir parcouru le tableau de données

Comment implémenter la fonctionnalité Tab

Pour créer un composant d'onglets qui fonctionne en douceur, vous devez gérer quel onglet est actuellement actif. Pensez à cela comme à montrer une seule section de contenu à la fois.

Pour y parvenir, commencez par établir un 'state' dans le composant App. Cet état gardera une trace de l'onglet actuellement actif.

  const [activeTab, setActiveTab] = useState(0);

L'état actif est initialisé avec l'index de l'onglet avec lequel vous souhaitez commencer.

Ensuite, il est utilisé pour montrer uniquement les données associées à cet index.

export default function TabContent({ petData, activeTab }) {
  return (
    <div className="tab__container ">
      <div className="tab__content">
        {/ Utilisation de l'index actif pour sélectionner des données particulières /}
        <img src={petData[activeTab].image} alt="" />
        <p> {petData[activeTab].fact}</p>
      </div>
    </div>
  );
}

Ce qui montre simplement le premier élément du tableau de données :

Image Affichage d'un élément de données du tableau

Vous pouvez réaliser la fonctionnalité de changement d'onglet en mettant à jour l'état de l'onglet actif en utilisant sa fonction setter.

Commencez par passer la fonction setter et l'état de l'onglet actif dans les boutons d'onglet via les props.

function App() {
  const [activeTab, setActiveTab] = useState(0);
  const petData = [ //...data ];

  return (
    <div className="main__container">
      <h1>Choose your pet</h1>
      <TabButtons
        activeTab={activeTab}
        setActiveTab={setActiveTab}
        petData={petData}
      />
      <TabContent activeTab={activeTab} petData={petData} />
    </div>
  );
}
export default App;

Ensuite, utilisez la fonction setter pour définir la valeur de l'état actif dans les données correspondantes via l'index.


export default function TabButtons({ petData, activeTab, setActiveTab }) {
  return (
    <div className="tab__header">
      {petData.map((item, index) => (
               <li
          className={`tab__button`}
          key={item.animal}
          onClick={() => setActiveTab(index)}>
          {item.animal}
        </li>
      ))}
    </div>
  );
}

Avec cela, votre composant d'onglets fonctionne et peut afficher des données dynamiques en fonction du bouton sur lequel vous cliquez. Félicitations !

Image Test de la fonctionnalité des onglets

Pour améliorer l'UX, ajoutez une classe active à l'onglet actuellement cliqué en utilisant son index. Cela applique la classe active à l'onglet dont la valeur d'index est la même que la valeur stockée dans l'état actif.

export default function TabButtons({ petData, activeTab, setActiveTab }) {
  return (
    <div className="tab__header">
      {petData.map((item, index) => (
        <li
          // Ajout d'une classe active lorsque l'index actuel correspond à l'onglet actuellement actif
          className={`${index === activeTab && "active"} tab__button`}
          key={item.animal}
          onClick={() => setActiveTab(index)}>
          {item.animal}
        </li>
      ))}
    </div>
  );
}

Ce qui donne le résultat suivant :

Image Fonctionnalité des onglets après avoir ajouté une classe active à l'onglet

Comment optimiser le composant Tab

Bien que votre composant d'onglets semble prêt à l'emploi, il existe encore des modifications que vous pouvez apporter pour mieux l'améliorer en termes de performance. Pour cela, vous pouvez utiliser React Dev Tools.

Il s'agit d'une extension de navigateur qui fournit une tonne d'outils utiles que les développeurs React peuvent utiliser pour inspecter et déboguer leurs applications. Rendez-vous sur le magasin d'extensions de votre navigateur et téléchargez l'extension.

Image Téléchargement des outils de développement React

Après l'avoir installée, l'inspection de n'importe quel site web React à partir des outils de développement de votre navigateur montre deux nouveaux onglets appelés Components et Profiler.

Dans cette application, nous utiliserons le Profiler, qui est utilisé pour mesurer combien de fois l'application React est rendue, combien de composants sont rendus et combien de temps les composants prennent pour être rendus.

Pour votre application, inspectez votre application React et ouvrez le profiler depuis le coin supérieur droit de votre écran.

Image Trouver le profiler dans les outils de développement

Dans votre profiler, cliquez sur le bouton d'enregistrement bleu et commencez un enregistrement de votre application React pour suivre les changements et les rendus.

Image Utilisation du profiler pour tester les changements

Le résultat de mon côté est un total de 0,6 ms pour le temps de rendu total avec les 3 composants se re-rendant (App = 0,2 ms, TabButtons = 0,3 ms et TabContent = 0,1 ms).

Le temps de rendu entier est tout à fait acceptable, mais il y a encore place à l'amélioration.

Avec le profiler indiquant que le composant app a déclenché le re-rendu, optimisons notre application pour réduire les re-rendus excessifs avec les étapes suivantes.

Commencez par créer un composant Tab et montez le tableau de données et l'état dans ce composant Tab. Vous faites cela parce que c'est le composant qui consomme les données et l'état et non le composant App.

import { useState } from "react";

const petData = [
  {
    animal: "Cheetah",
    fact: "Cheetahs are the fastest land animals, capable of reaching speeds up to 75 mph.",
    image: "../src/assets/6.svg",
  },
  {
    animal: "Koala",
    fact: "Koalas sleep around 20 hours a day and are known for their eucalyptus diet.",
    image: "../src/assets/3.svg",
  },
  {
    animal: "Elephant",
    fact: "Elephants have the largest brains among land animals and demonstrate remarkable intelligence.",
    image: "../src/assets/1.svg",
  },
  {
    animal: "Zebra",
    fact: "Zebras have distinctive black and white stripes that act as a natural defense against predators.",
    image: "../src/assets/7.svg",
  },
  {
    animal: "Horse",
    fact: "Horses have excellent memory and are capable of recognizing human emotions.",
    image: "../src/assets/5.svg",
  },
];

export default function Tab() {
  const [activeTab, setActiveTab] = useState(0);
  return <></>;
}

Ensuite, créez localement le JSX pour ce projet. Cela élimine le besoin de créer des composants excessifs juste pour le JSX.

export default function Tab() {
  const [activeTab, setActiveTab] = useState(0);
  return (
    <>
      <div className="tab__header">
        {petData.map((item, index) => (
          <li
            className={`${index === activeTab && "active"} tab__button`}
            key={item.animal}
            onClick={() => setActiveTab(index)}>
            {item.animal}
          </li>
        ))}
      </div>
      <div className="tab__container ">
        <div className="tab__content">
          <img src={petData[activeTab].image} alt="" />
          <p> {petData[activeTab].fact}</p>
        </div>
      </div>
    </>
  );
}

Et maintenant, relancer le profiler avec votre nouvelle structure d'application donne le résultat suivant :

Image Profiler après l'optimisation de l'application

Comme vous pouvez le voir, le nouveau temps de rendu est de 0,3 ms, améliorant la vitesse de 50 %, avec le composant d'application qui ne se re-rend pas et les éléments JSX supplémentaires supprimés.

Il est important de noter que cet exemple est relatif à la taille du composant d'onglets. Dans les plus grands, il est assez courant de voir le composant d'onglets divisé en composants plus petits mais dans le même fichier.

Comment animer le composant

Pour l'animation, nous utiliserons Framer Motion, une bibliothèque d'animation open-source conçue pour React. Elle offre une API simple et expressive pour générer des animations complexes.

Pour une explication plus approfondie du fonctionnement de la bibliothèque, consultez ce guide sur l'utilisation de framer motion pour animer les routes dans React.

Pour utiliser la bibliothèque, commencez par l'installer dans votre projet en utilisant l'invite :

npm i framer-motion

Ensuite, importez les propriétés requises depuis la bibliothèque.

import { AnimatePresence, motion } from "framer-motion";

Ensuite, faites en sorte que tous les éléments que vous souhaitez animer soient des éléments de mouvement.

export default function Tab() {
  return (
    <>
        <motion.div className="tab__container">
          <div className="tab__header">
            {petData.map((item, index) => (
              <li
                className={`${index === activeTab && "active"} tab__button`}
                key={item.animal}
                onClick={() => setActiveTab(index)}>
                {item.animal}
              </li>
            ))}
          </div>
          <div className="tab__content">
            <motion.img
              src={petData[activeTab].image}
              alt=""
            />
            <motion.p>
              {petData[activeTab].fact}
            </motion.p>
          </div>
        </motion.div>

    </>
  );
}

Ensuite, créez des objets d'animation pour les éléments que vous souhaitez animer. Pour votre onglet, cela crée une animation d'échelle pour l'image et une animation de fondu et de glissement pour le texte.

const contentVariants = {
  initial: { y: "100%", opacity: 0 },
  animate: { y: "0", opacity: 1 },
  exit: { y: "100%", opacity: 0 },
};

const imgVariants = {
  initial: { scale: 0.1 },
  animate: { scale: 1 },
  exit: { scale: 0.1 },
};

Après cela, passez-les dans le JSX, en spécifiant leurs états initial, animé et de sortie.

export default function Tab() {
  const [activeTab, setActiveTab] = useState(0);
  return (
    <>

        <motion.div className="tab__container" key={activeTab}>
          <div className="tab__header">
            {petData.map((item, index) => (
              <li
                className={`${index === activeTab && "active"} tab__button`}
                key={item.animal}
                onClick={() => setActiveTab(index)}>
                {item.animal}
              </li>
            ))}
          </div>
          <div className="tab__content">
            <motion.img
              src={petData[activeTab].image}
              alt=""
              initial="initial"
              animate="animate"
              exit="exit"
              variants={imgVariants}
              transition={{ duration: 0.5 }}
            />
            <motion.p
              variants={contentVariants}
              initial="initial"
              animate="animate"
              exit="exit"
              transition={{ duration: 0.5 }}>
              {petData[activeTab].fact}
            </motion.p>
          </div>
        </motion.div>

    </>
  );
}

Enfin, enveloppez votre composant avec le composant AnimatePresence pour détecter lorsque vous changez d'onglet afin de déclencher les animations de sortie :

export default function Tab() {

  return (
    <>
      <AnimatePresence mode="wait">
        <motion.div className="tab__container" key={activeTab}>
          <div className="tab__header">
            {petData.map((item, index) => (
              <li
                className={`${index === activeTab && "active"} tab__button`}
                key={item.animal}
                onClick={() => setActiveTab(index)}>
                {item.animal}
              </li>
            ))}
          </div>
          <div className="tab__content">
            <motion.img
              src={petData[activeTab].image}
              alt=""
              initial="initial"
              animate="animate"
              exit="exit"
              variants={imgVariants}
              transition={{ duration: 0.5 }}
            />
            <motion.p
              variants={contentVariants}
              initial="initial"
              animate="animate"
              exit="exit"
              transition={{ duration: 0.5 }}>
              {petData[activeTab].fact}
            </motion.p>
          </div>
        </motion.div>
      </AnimatePresence>
    </>
  );
}

Note : Framer motion utilise la prop key pour détecter les changements entre les éléments. La prop mode définie sur wait dans AnimatePresence aide framer motion à déclencher les animations de sortie avant les animations d'entrée.

Et avec cela, votre composant Tab est entièrement fonctionnel et animé. Bravo ! 

Image composant à onglets entièrement fonctionnel et animé

Pour référence, voici le code complet :

import { AnimatePresence, motion } from "framer-motion";

import { useState } from "react";

const petData = [
  {
    animal: "Cheetah",
    fact: "Cheetahs are the fastest land animals, capable of reaching speeds up to 75 mph.",
    image: "../src/assets/6.svg",
  },
  {
    animal: "Koala",
    fact: "Koalas sleep around 20 hours a day and are known for their eucalyptus diet.",
    image: "../src/assets/3.svg",
  },
  {
    animal: "Elephant",
    fact: "Elephants have the largest brains among land animals and demonstrate remarkable intelligence.",
    image: "../src/assets/1.svg",
  },
  {
    animal: "Zebra",
    fact: "Zebras have distinctive black and white stripes that act as a natural defense against predators.",
    image: "../src/assets/7.svg",
  },
  {
    animal: "Horse",
    fact: "Horses have excellent memory and are capable of recognizing human emotions.",
    image: "../src/assets/5.svg",
  },
];

const contentVariants = {
  initial: { y: "100%", opacity: 0 },
  animate: { y: "0", opacity: 1 },
  exit: { y: "100%", opacity: 0 },
};

const imgVariants = {
  initial: { scale: 0.1 },
  animate: { scale: 1 },
  exit: { scale: 0.1 },
};

export default function Tab() {
  const [activeTab, setActiveTab] = useState(0);
  return (
    <>
      <AnimatePresence mode="wait">
        <motion.div className="tab__container" key={activeTab}>
          <div className="tab__header">
            {petData.map((item, index) => (
              <li
                className={`${index === activeTab && "active"} tab__button`}
                key={item.animal}
                onClick={() => setActiveTab(index)}>
                {item.animal}
              </li>
            ))}
          </div>
          <div className="tab__content">
            <motion.img
              src={petData[activeTab].image}
              alt=""
              initial="initial"
              animate="animate"
              exit="exit"
              variants={imgVariants}
              transition={{ duration: 0.5 }}
            />
            <motion.p
              variants={contentVariants}
              initial="initial"
              animate="animate"
              exit="exit"
              transition={{ duration: 0.5 }}>
              {petData[activeTab].fact}
            </motion.p>
          </div>
        </motion.div>
      </AnimatePresence>
    </>
  );
}

Autres méthodes pour affiner les performances

Bien que votre composant d'onglets React soit fonctionnel et animé, il existe des opportunités pour une optimisation supplémentaire afin d'assurer des performances élevées, en particulier dans des scénarios impliquant de grands ensembles de données ou une récupération de données asynchrone. Explorons quelques stratégies pour affiner votre composant d'onglets.

Considérations sur les données

  • Taille du composant d'onglets : Vérifiez la taille de votre composant d'onglets, surtout si vous traitez une grande quantité de données. Envisagez le chargement paresseux ou la pagination pour améliorer les temps de rendu initiaux.
  • Chargement asynchrone des données : Si vos données sont asynchrones, implémentez des états de chargement pour améliorer l'expérience utilisateur. Optimisez la logique de rendu pour gérer efficacement le chargement des données.

React Profiler

  • Identification et réduction des re-rendus inutiles : En plus d'utiliser React DevTools Profiler pour analyser le comportement de rendu des composants, utilisez des hooks React comme React.memo et React.callback pour optimiser et mettre en cache vos données.

Structure des composants

  • Structure granulaire des composants : Pour les composants d'onglets plus grands, envisagez de décomposer la structure en composants plus petits et granulaires. Cela permet une meilleure maintenabilité et peut améliorer les performances de rendu.

Fractionnement du code

  • Imports dynamiques pour le fractionnement du code : Implémentez des imports dynamiques pour le fractionnement du code, surtout si votre application React devient plus complexe. Cela garantit que seul le code nécessaire se charge lorsqu'un onglet spécifique est sélectionné.

Conception réactive

  • Optimisation pour différentes tailles d'écran : Assurez-vous que votre composant d'onglets est réactif aux différentes tailles d'écran. Envisagez des requêtes média et une conception adaptative pour offrir une expérience optimale sur divers appareils.

Mise en cache du navigateur

  • Optimisation des actifs avec la mise en cache du navigateur : Utilisez la mise en cache du navigateur pour les actifs statiques, tels que les images, afin de réduire les temps de chargement. Envisagez d'optimiser et de compresser les images pour réduire leur impact sur les performances.

Test et profilage

  • Test et profilage continus : Testez votre composant d'onglets dans diverses conditions et profilez-le. Utilisez des outils comme Lighthouse ou Web Vitals pour suivre les métriques de performance et résoudre tout problème qui pourrait survenir.

En mettant en œuvre ces stratégies, vous pouvez élever votre composant d'onglets React de simplement fonctionnel à hautement performant, assurant une expérience utilisateur fluide dans différents scénarios et ensembles de données.

Voici un lien vers le dépôt : GitHub

Et la version live : Démo Live

Conclusion

Vous avez réussi à construire des onglets React qui sont plus que simplement fonctionnels – ils sont optimisés pour une expérience utilisateur fluide. De la configuration de l'environnement à l'ajout d'animations, vous avez couvert l'essentiel.

Alors que vous affinez et optimisez vos onglets, rappelez-vous qu'ils jouent un rôle crucial dans la navigation utilisateur. Continuez à coder et que vos onglets React offrent une expérience fiable et conviviale.

Bon codage !

Informations de contact

Vous souhaitez me contacter ? N'hésitez pas à me contacter sur les plateformes suivantes :