window.pipedriveLeadboosterConfig = { base : 'leadbooster-chat.pipedrive.com', companyId : 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', version : 2, } ;(function () { var w = window if (w.LeadBooster) { console.warn('LeadBooster existe déjà') } else { w.LeadBooster = { q : [], on : function (n, h) { this.q.push({ t : 'o', n : n, h : h }) }, trigger : function (n) { this.q.push({ t : 't', n : n }) }, } } })() Visibilité des composants dans React avec rendu conditionnel et protections - The Codest
The Codest
  • A propos de nous
  • Services
    • Développement de logiciels
      • Développement frontal
      • Développement backend
    • Staff Augmentation
      • Développeurs frontaux
      • Développeurs backend
      • Ingénieurs des données
      • Ingénieurs en informatique dématérialisée
      • Ingénieurs AQ
      • Autres
    • Conseil consultatif
      • Audit et conseil
  • Industries
    • Fintech et banque
    • E-commerce
    • Adtech
    • Santé (Healthtech)
    • Fabrication
    • Logistique
    • Automobile
    • IOT
  • Valeur pour
    • CEO
    • CTO
    • Gestionnaire des livraisons
  • Notre équipe
  • Études de cas
  • Savoir comment
    • Blog
    • Rencontres
    • Webinaires
    • Ressources
Carrières Prendre contact
  • A propos de nous
  • Services
    • Développement de logiciels
      • Développement frontal
      • Développement backend
    • Staff Augmentation
      • Développeurs frontaux
      • Développeurs backend
      • Ingénieurs des données
      • Ingénieurs en informatique dématérialisée
      • Ingénieurs AQ
      • Autres
    • Conseil consultatif
      • Audit et conseil
  • Valeur pour
    • CEO
    • CTO
    • Gestionnaire des livraisons
  • Notre équipe
  • Études de cas
  • Savoir comment
    • Blog
    • Rencontres
    • Webinaires
    • Ressources
Carrières Prendre contact
Flèche arrière RETOUR
2023-05-19
Développement de logiciels

Visibilité des composants dans React avec rendu conditionnel et protections

Bartlomiej Kuczynski

Découvrez comment simplifier et améliorer la visibilité des composants dans React à l'aide du rendu conditionnel et des composants de garde.

Aujourd'hui, je voudrais parler de la manière de contrôler visibilité des composants en React. Mais avant de commencer, il y a une petite
clause de non-responsabilité :

La solution présentée n'est pas très sûre en ce qui concerne la protection de votre application contre les "pirates" (quels qu'ils soient).
Rappelez-vous que vous devez protéger vos points d'extrémité et utiliser de bonnes pratiques dans la conception de l'application. Cette solution ne fait que
Cette solution ne fait que faciliter un peu votre travail.

Tâche, solution au problème ou objectif à atteindre

L'une des fonctionnalités les plus courantes consiste à n'afficher le composant que pour un groupe d'utilisateurs disposant de certains droits spécifiques,
rôles ou privilèges. La solution la plus courante consiste à ajouter des sià codeL'application de l'article 5 de la loi sur la protection de l'environnement permet de vérifier manuellement les conditions et d'afficher ou non les éléments.

Jetons un coup d'œil à SimpleAppHeader qui contient peu d'éléments de navigation.

<!-- wp:paragraph -->
<p><code>typescript jsx<br>
export const SimpleAppHeader : FC = () =&gt; {<br>
    return (<br>)
        <br>
            <nav><br>
                <ul><br>
                    {<br>
                        currentUser.role === "ADMIN" &amp;&amp;<br><br>L'utilisateur actuel a un rôle d'administrateur.
                        <li>Composant réservé à l'administrateur</li><br>
                    }<br><br><br>L'utilisateur actuel a un rôle à jouer dans l'organisation de son travail.
                    {<br><br>L'utilisateur actuel
                        currentUser.role === "USER" &amp;&amp;<br> <li>Composant réservé aux utilisateurs</li><br>.
                        <li>Composant utilisateur uniquement</li><br>.
                    }<br><br><br>L'utilisateur actuel a un rôle à jouer dans la vie de l'entreprise.
                    {<br><br>L'utilisateur actuel est le seul à avoir un rôle à jouer dans le système.
                        (currentUser.role === "ADMIN" || currentUser.role === "USER") &amp;&amp;<br> <li>Admin et User only component</li><br>.
                        <li>Composant réservé aux administrateurs et aux utilisateurs</li><br>.
                    }<br><br>Les éléments d'utilisation générale<br><br>Les éléments d'utilisation générale
                    <li>Élément d'utilisation générale</li><br>
                </ul><br>
            </nav><br><br><br>Nav
        </header><br><br>Les éléments d'utilisation générale
    )<br>
}<br>
</code></p>
<!-- /wp:paragraph -->

Cela semble "pas mal". Il serait probablement possible d'encapsuler les contrôles dans des fonctions pour réduire la complexité. utilisateur actuel est un objet quelconque
qui a rôle mais il peut s'agir de tout ce que nous souhaitons utiliser comme objet de notre mécanisme de contrôle.

Ce code pose quelques problèmes. Si le code projet grandit, nous utilisons probablement ces constructions dans de nombreux endroits. Nous devons donc les copier,
d'une manière ou d'une autre, des conditions. Ce code est difficile à maintenir et à modifier à l'avenir. En particulier lorsque les règles d'accès changent pendant
temps p.ex. nous devons changer utilisateur actuel en quelque chose d'autre. Il est très difficile de le tester. Il faut écrire de nombreux tests
juste pour vérifier si votre état est correct.

Simplification

Il est temps de simplifier un peu ce code. Nous pourrions extraire certaines méthodes et rendre le code plus court et moins complexe :

const isAdmin = (role : string) : boolean => role === "ADMIN" ;
const isUser = (rôle : chaîne) : booléen => rôle === "USER" ;
const isAdminOrUser = (role : string) : boolean => isAdmin(role) || isUser(role) ;

export const SimplifiedAppHeader : FC = () => {
return (

{

isAdmin(currentUser.role) &&
Composant réservé aux administrateurs

}
{
isUser(currentUser.role) &&

Composant utilisateur uniquement

}
{
(isAdminOrUser(currentUser.role)) &&

Composant réservé aux administrateurs et aux utilisateurs

}

Élément d'utilisation générale

)
}
```

Cela semble prometteur. Nous réduisons le bruit et les lignes répétitives. Le code est plus lisible et plus facile à maintenir. Mais jetez un coup d'œil à
fonction isAdminOrUser. Nous n'avons que deux rôles. Si nous introduisons un troisième rôle, nous devons créer un autre ensemble de fonctions
qui combine les rôles. Il est temps de passer à une autre version.

Filtrage

Introduisons la fonction aRôle qui remplacera notre isX fonctions.

const hasRole = (role : string, requiredRole : string[]) : boolean => {
let found : string | undefined = requiredRole.find(s => role === s) ;
return found !== undefined ;
}

export const FilteringAppHeader : FC = () => {
return (

{

hasRole(currentUser.role, ["ADMIN"]) &&
Composant réservé aux administrateurs

}
{
hasRole(currentUser.role, ["USER"]) &&

Composant utilisateur uniquement

}
{
hasRole(currentUser.role, ["ADMIN", "USER"]) &&

Composant réservé aux administrateurs et aux utilisateurs

}

Élément d'utilisation générale

)
}
```

Le résultat est maintenant satisfaisant. Nous avons toujours des conditions dans la partie html du code, mais maintenant nous pouvons tester aRôle et de la confiance qu'elle suscite.
sera utilisé avec les bons paramètres. Il est désormais plus facile d'ajouter ou de modifier des rôles. Nous utilisons un tableau qui contient tous les
que nous devons mettre en place.

Toutefois, cette solution est contraignante pour utilisateur actuel l'objet. L'hypothèse est que l'objet est en quelque sorte global ou facile d'accès en
n'importe où dans l'application. Nous pouvons donc essayer de l'encapsuler. Bien sûr, nous pouvons le déplacer vers aRôle fonction :

 const hasRole = (requiredRole : string[]) : boolean => {
     let found : string | undefined = requiredRole.find(s => currentUser.role === s) ;
     return found !== undefined ;
 }

Mais cela ne nous donne presque rien.

Les Garde Composant

Il est temps de créer un composant qui encapsule toute la logique. Je l'ai nommé Garde et voici comment je veux l'utiliser.

 export const GuardedAppHeader : FC = () => {
     return (
         
             
  • Composant réservé aux administrateurs
  • Composant réservé aux utilisateurs
  • Composant administrateur et utilisateur
  • Élément d'utilisation générale
) ; }

Le composant a besoin de deux propriétés. La première enfants responsable du contenu gardé. Deuxième rôles requis que
Le système de gestion des rôles qui nous permet d'accéder à l'information.

Nous avons besoin d'une représentation de cette structure. C'est très simple. Nous étendons le type React.PropsWithChildren qui a enfants
propriété. Bien entendu, vous pouvez ajouter manuellement cette propriété à votre type et omettre l'extension.

interface IGuardProps extends React.PropsWithChildren {
requiredRoles : string[] ;
}

Le composant lui-même est également simple. Nous réutiliserons aRôle ici.

export const Guard = (props : IGuardProps) => {
const hasRole = (requiredRole : string[]) : boolean => {
let found : string | undefined = requiredRole.find(s => currentUser.role === s) ;
return found !== undefined ;
}

if (hasRole(props.requiredRoles)) {
    return (
        
            {props.children}
        
    ) ;
} else {
    return  ;
}
}
"`

Et je pourrais dire stop ici, mais ce serait trop facile. Nous avons maintenant un composant, et nous pouvons l'utiliser à l'extrême 😀

`GuardService`

La première étape sera l'externalisation des contrôles. utilisateur actuel est une valeur codée en dur. Je voudrais encapsuler cette valeur
dans un service qui "saura" comment vérifier les rôles. Techniquement, cela signifie que nous déplaçons aRôle à une autre fonction
classe.

Je crée une interface simple IGuardService qui n'a qu'une seule propriété - aRôle.

export interface IGuardService {
checkRole : (roles : string[]) => boolean ;
}

Une mise en œuvre simple pourrait ressembler à ce qui suit

class SimpleGuard implements IGuardService {
checkRole(roles : string[]) : boolean {
let found : string | undefined = roles.find(e => e === currentUser.role) ;
return found !== undefined ;
}
}

Pour l'utiliser, nous devons modifier IGuardProperties et le cas d'utilisation.

export interface IGuardProps extends React.PropsWithChildren {
requiredRoles : string[] ;
guardService : IGuardService ;
}

// ...

const AppHeader : FC = () => {
const guardService = new SimpleGuard() ;
return (

Composant réservé aux administrateurs
 

Composant réservé à l'utilisateur

Composant administrateur et utilisateur
 
 

Élément d'utilisation générale

 

) ;
}
```

Le composant se présente maintenant comme suit :

 export const Guard = (props : IGuardProps) => {
     if (props.guardService.checkRole(props.requiredRoles)) {
         return (
             
                 {props.children}
             
         ) ;
     } else {
         return  ;
     }
 }
 

Beaucoup mieux. Service de garde nous séparent de la logique qui vérifie les rôles. Nous pouvons la modifier sans conséquences pour notre
composant. Le cas d'utilisation le plus courant est l'utilisation d'un simulacre dans les tests et d'une implémentation "réelle" dans le code de production.

Élément interdit

La prochaine amélioration portera sur la gestion des commandes personnalisées. Interdit élément. La solution actuelle rend l'élément vide. Nous devons d'abord
changer IGuardProps l'ajout d'une fonction qui sera rendue à cet élément.

 export interface IGuardProps extends React.PropsWithChildren {
     requiredRoles : string[] ;
     guardService : IGuardService ;
     forbidden? : () => React.ReactNode ;
 }

Il s'agit d'une propriété facultative, dont le nom se termine par un point d'interrogation. Il peut donc s'agir d'une fonction ou d'une indéfini. Nous devons
le traiter en Garde de la composante.

export const Guard = (props : IGuardProps) => {
if (props.guardService.checkRole(props.requiredRoles)) {
return (

{props.children}

) ;
} else if (props.forbidden === undefined) {
return  ;
} else {
return (
{props.forbidden()}

) ;
}
}

// ...

export const AppHeader : FC = () => {
const guardService = new SimpleGuard() ;
return (

Composant réservé aux administrateurs
 

Composant réservé à l'utilisateur

Interdit - seul le modérateur peut le voir
}>
 

Composant modérateur

 

Composant administrateur et utilisateur
 
 

Élément d'utilisation générale

 

) ;
}
```

Flexibilité des types

Il est temps de procéder au dernier grand changement. La version actuelle du composant ne prend en charge que les rôles de chaîne de caractères. Nous pourrions avoir plusieurs
les types de propriétés que nous souhaitons vérifier. Les nombres ou les types personnalisés n'ont rien de spécial. Je vais ajouter le support des génériques.

La première étape consiste à modifier les IGuardService interface. Les implémentations dépendront du type de valeur testée. Elle pourrait
n'importe quoi, l'interface doit donc le gérer.

 export interface IGuardService {
     checkRole : (roles : ROLE[]) => boolean ;
 }

Il prend maintenant un tableau de RÔLE type générique. Notre mise en œuvre simple sera légèrement modifiée.

 class SimpleGuard implements IGuardService {
     checkRole(roles : string[]) : boolean {
         let found : string | undefined = roles.find(e => e === currentUser.role) ;
         return found !== undefined ;
     }
 }

Nous devons ajouter un paramètre de type, mais nous pourrions préparer une mise en œuvre qui prenne en charge les éléments suivants IRole l'interface.

interface IRole {
name : string ;
}

//...
class RoleGuardService implements IGuardService {
checkRole(roles : IRole[]) : boolean {
let found : IRole | undefined = roles.find(e => e === userWithRole.role) ;
return found !== undefined ;
}
}
```

La deuxième étape consiste à propager cette modification à IGuardProps.

<interface IGuardProps extends React.PropsWithChildren {
     requiredRoles : ROLE[] ;
     guardService : IGuardService ;
     forbidden? : () => React.ReactNode ;
 }

Et respectivement à Garde de la composante.

export const Guard = (props : IGuardProps) => {
     if (props.guardService.checkRole(props.requiredRoles)) {
         return (
             
                 {props.children}
             
         ) ;
     } else if (props.forbidden === undefined) {
         return  ;
     } else {
         return (
                 {props.forbidden()}
             
         ) ;
     }
 }

Et nos cas d'utilisation

export const AppHeader : FC = () =&gt; {
     const guardService = new SimpleGuard() ;
     const roleService = new RoleGuardService() ;
     return (
         <header>
             <nav>
                 <ul>
                     <Guard<IRole&gt; requiredRoles={[{nom : "ADMIN"}]} guardService={roleService}&gt;
                         <li>Composant réservé aux administrateurs</li>
                     </Guard>
                     <Guard<string&gt; requiredRoles={["USER"]} guardService={guardService}&gt;
                         <li>Composant réservé à l'utilisateur</li>
                     </Guard>
                     <Guard<string&gt; requiredRoles={["MODERATOR"]} guardService={guardService}
                                    forbidden={() =&gt; <div>Interdit - seul le modérateur peut voir ceci</div>}>
                         <li>Composant du modérateur</li>
                     </Guard>
                     <Guard<string&gt; requiredRoles={["USER", "ADMIN"]} guardService={guardService}&gt;
                         <li>Composant Admin et Utilisateur</li>
                     </Guard>
                     <li>Élément d'utilisation générale</li>
                 </ul>
             </nav>
         </header>
     );
 }

Dans cet exemple, j'utilise les deux implémentations de IGuardservice à des fins d'illustration. Dans les cas d'utilisation réels, vous
n'en utiliseront probablement qu'un seul.

Composants spécialisés et emboîtement

Les Garde peuvent être imbriqués. Rappelez-vous simplement que l'accès sera résolu dans l'ordre de l'instance la plus externe.

export const NestAppHeader : FC = () =&gt; {
     const guardService = new SimpleGuard() ;
     return (
         <header>
             <nav>
                 <ul>
                     <Guard<string&gt; requiredRoles={["USER", "ADMIN"]} guardService={guardService}&gt;
                         <Guard<string&gt; requiredRoles={["ADMIN"]} guardService={guardService}&gt;
                             <li>Composant réservé aux administrateurs</li>
                         </Guard>
                         <Guard<string&gt; requiredRoles={["USER"]} guardService={guardService}&gt;
                             <li>Composant réservé à l'utilisateur</li>
                         </Guard>
                         <li>Composant Admin et Utilisateur</li>
                         <Guard<string&gt; requiredRoles={["MODERATOR"]} guardService={guardService}
                                        forbidden={() =&gt; <div>Interdit - seul le modérateur peut voir ceci</div>}>
                             <li>Composant du modérateur</li>
                         </Guard>
                     </Guard>
                     <li>Élément d'utilisation générale</li>
                 </ul>
             </nav>
         </header>
     );
 }

Dans l'exemple ci-dessus Composant du modérateur ne peut jamais apparaître, car l'utilisateur ne peut assumer qu'un seul rôle. Première Garde limites
rôles à ADMIN et UTILISATEURAinsi MODÉRATEUR ne passera jamais le premier contrôle.

Nous pouvons construire des composants spécialisés qui masquent certaines propriétés.

export const AdminGuard = (props : Omit) => {
return 
{props.children}

}

//...
export const SpecializedAppHeader : FC = () => {
const guardService = new SimpleGuard() ;
return (

Composant réservé aux administrateurs
 


Composant réservé aux utilisateurs


Interdit - seul le modérateur peut voir ceci
}>

Composant modérateur



Composant Admin et Utilisateur

 

Élément d'utilisation générale

) ;
}
```

Dans ce cas AdminGuard prédéfinir ADMIN rôle. En conséquence, nous devons définir explicitement le type de RÔLE type
paramètre.

Résumé

Dans cet article, je vous montre comment créer et utiliser des Garde composant en React. Nous partons d'un code complexe difficile à
lire et à maintenir. Nous le faisons évoluer vers un état plus convivial pour les développeurs et introduisons des composants fonctionnels personnalisés. Ensuite, nous
étendre le composant en ajoutant des fonctionnalités supplémentaires, refactoriser le service d'extraction et enfin ajouter des types génériques.

Enfin, nous disposons d'un composant qui peut être imbriqué et qui est facile à tester et à maintenir.

Articles connexes

Développement de logiciels

Avantages et inconvénients de React

Pourquoi est-il utile d'utiliser React ? Quels sont les avantages de la bibliothèque JavaScript ? Pour trouver les réponses, plongez-vous dans cet article et découvrez les avantages réels de l'utilisation de React.

The Codest
Cezary Goralski Software Engineer

Abonnez-vous à notre base de connaissances et restez au courant de l'expertise du secteur des technologies de l'information.

    A propos de nous

    The Codest - Entreprise internationale de développement de logiciels avec des centres technologiques en Pologne.

    Royaume-Uni - Siège

    • Bureau 303B, 182-184 High Street North E6 2JA
      Londres, Angleterre

    Pologne - Les pôles technologiques locaux

    • Parc de bureaux Fabryczna, Aleja
      Pokoju 18, 31-564 Kraków
    • Brain Embassy, Konstruktorska
      11, 02-673 Varsovie, Pologne

      The Codest

    • Accueil
    • A propos de nous
    • Services
    • Études de cas
    • Savoir comment
    • Carrières
    • Dictionnaire

      Services

    • Conseil consultatif
    • Développement de logiciels
    • Développement backend
    • Développement frontal
    • Staff Augmentation
    • Développeurs backend
    • Ingénieurs en informatique dématérialisée
    • Ingénieurs des données
    • Autres
    • Ingénieurs AQ

      Ressources

    • Faits et mythes concernant la coopération avec un partenaire externe de développement de logiciels
    • Des États-Unis à l'Europe : Pourquoi les startups américaines décident-elles de se délocaliser en Europe ?
    • Comparaison des pôles de développement Tech Offshore : Tech Offshore Europe (Pologne), ASEAN (Philippines), Eurasie (Turquie)
    • Quels sont les principaux défis des CTO et des DSI ?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • Conditions d'utilisation du site web

    Copyright © 2025 par The Codest. Tous droits réservés.

    fr_FRFrench
    en_USEnglish de_DEGerman sv_SESwedish da_DKDanish nb_NONorwegian fiFinnish pl_PLPolish arArabic it_ITItalian jaJapanese ko_KRKorean es_ESSpanish nl_NLDutch etEstonian elGreek fr_FRFrench