window.pipedriveLeadboosterConfig = { base: 'leadbooster-chat.pipedrive.com', companyId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', version: 2, } ;(funktion () { var w = vindue if (w.LeadBooster) { console.warn('LeadBooster findes allerede') } 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 }) }, } } })() Komponenters synlighed i React med betinget gengivelse og vagter - The Codest
Codest
  • Om os
  • Serviceydelser
    • Udvikling af software
      • Frontend-udvikling
      • Backend-udvikling
    • Staff Augmentation
      • Frontend-udviklere
      • Backend-udviklere
      • Dataingeniører
      • Cloud-ingeniører
      • QA-ingeniører
      • Andet
    • Det rådgivende
      • Revision og rådgivning
  • Industrier
    • Fintech og bankvirksomhed
    • E-commerce
    • Adtech
    • Sundhedsteknologi
    • Produktion
    • Logistik
    • Biler
    • IOT
  • Værdi for
    • ADMINISTRERENDE DIREKTØR
    • CTO
    • Leder af levering
  • Vores team
  • Casestudier
  • Ved hvordan
    • Blog
    • Møder
    • Webinarer
    • Ressourcer
Karriere Tag kontakt til os
  • Om os
  • Serviceydelser
    • Udvikling af software
      • Frontend-udvikling
      • Backend-udvikling
    • Staff Augmentation
      • Frontend-udviklere
      • Backend-udviklere
      • Dataingeniører
      • Cloud-ingeniører
      • QA-ingeniører
      • Andet
    • Det rådgivende
      • Revision og rådgivning
  • Værdi for
    • ADMINISTRERENDE DIREKTØR
    • CTO
    • Leder af levering
  • Vores team
  • Casestudier
  • Ved hvordan
    • Blog
    • Møder
    • Webinarer
    • Ressourcer
Karriere Tag kontakt til os
Pil tilbage GÅ TILBAGE
2023-05-19
Udvikling af software

Komponentsynlighed i React med betinget gengivelse og vagter

Bartlomiej Kuczynski

Lær, hvordan du kan forenkle og forbedre komponenternes synlighed i React ved hjælp af betinget gengivelse og beskyttelseselementer.

I dag vil jeg gerne diskutere, hvordan man kan kontrollere komponentens synlighed i React. Men før vi begynder, er der en lille
Ansvarsfraskrivelse:

Den præsenterede løsning er ikke særlig sikker i forhold til at beskytte din applikation mod "hackere" (hvem der så end er).
Husk, at du skal beskytte dine slutpunkter og bruge god praksis i applikationsdesign. Denne løsning gør kun
gør kun dit arbejde lidt lettere.

Opgave, problemløsning, eller hvad vi gerne vil opnå

En af de mest almindelige funktioner er kun at vise komponenter for en række brugere, der har nogle specifikke rettigheder,
roller eller rettigheder. En almindelig løsning er at tilføje nogle hviss til Kodemanuelt kontrollere forholdene og vise eller ikke vise elementer.

Lad os tage et kig på SimpleAppHeader komponent, der indeholder få navigationselementer.

<!-- wp:paragraph -->
<p><code>typescript jsx<br>
export const SimpleAppHeader: FC = () =&gt; {<br>
    return (<br>
        <header><br>
            <nav><br>
                <ul><br>
                    {<br>
                        currentUser.role === "ADMIN" &amp;&amp;<br>
                        <li>Komponent kun til administrator</li><br>
                    }<br>
                    {<br>
                        currentUser.role === "USER" &amp;&amp;<br>
                        <li>Kun bruger-komponent</li><br>.
                    }<br>
                    {<br>
                        (currentUser.role === "ADMIN" || currentUser.role === "USER") &amp;&amp;<br>
                        <li>Kun administrator- og brugerkomponent</li><br>
                    }<br>
                    <li>Generel brug af elementet</li><br>
                </ul><br>
            </nav><br>
        </header><br>
    )<br>
}<br>
</code></p>
<!-- /wp:paragraph -->

Det ser "ikke dårligt" ud. Du kan sikkert indkapsle checks i funktioner for at reducere kompleksiteten. nuværende bruger er et eller andet objekt
der har rolle egenskab, men det kan være hvad som helst, som vi gerne vil bruge som genstand for vores kontrolmekanisme.

Denne kode har nogle problemer. Hvis projekt vokser, bruger vi sikkert de konstruktioner mange steder. Så vi er nødt til at kopiere,
på en eller anden måde, betingelser. Denne kode er svær at vedligeholde og ændre i fremtiden. Især når adgangsreglerne ændres i løbet af
tid f.eks. vi er nødt til at ændre nuværende bruger til noget andet. Det er meget svært at teste. Du er nødt til at skrive mange tests
bare for at tjekke, om din tilstand er ok.

Forenkling

Det er tid til at forenkle koden lidt. Vi kan trække nogle metoder ud og gøre koden kortere og mindre kompleks:

const isAdmin = (role: string): boolean => role === "ADMIN";
const isUser = (role: string): boolean => role === "USER";
const isAdminOrUser = (role: string): boolean => isAdmin(role) || isUser(role);

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

{

isAdmin(currentUser.role) &&
Kun administrator-komponent

}
{
isUser(currentUser.role) &&

Kun bruger-komponent

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

Kun administrator- og brugerkomponent

}

Element til generel brug

)
}
```

Det ser lovende ud. Vi reducerer støj og gentagne linjer. Koden er mere læsbar og lettere at vedligeholde. Men tag et kig på
funktion isAdminOrUser. Vi har kun to roller. Hvis vi indfører en tredje rolle, skal vi oprette et andet sæt funktioner
der kombinerer roller. Tid til en ny version.

Filtrering

Lad os indføre funktionen harRolle der vil være erstatning for vores isX funktioner.

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"]) &&
Kun administrator-komponent

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

Kun bruger-komponent

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

Kun administrator- og brugerkomponent

}

Element til generel brug

)
}
```

Nu ser det godt ud. Vi har stadig betingelser i html-delen af koden, men nu kan vi teste harRolle funktion og stole på, at den
vil blive brugt med det korrekte sæt parametre. Det er nu nemmere at tilføje eller ændre roller. Vi bruger et array, der indeholder alle
roller, som vi skal have på plads.

Denne løsning er dog bundet til nuværende bruger objekt. Antagelsen er, at objektet på en eller anden måde er globalt eller let at få adgang til i
et hvilket som helst sted i applikationen. Så vi kan prøve at indkapsle det. Vi kan selvfølgelig flytte det til harRolle funktion:

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

Men det giver os næsten ingenting.

Den Vagt Komponent

Tid til at skabe en komponent, der indkapsler hele logikken. Jeg navngav den Vagt og det er sådan, jeg vil bruge den.

 export const GuardedAppHeader: FC = () => {
     return (
         
             
  • Komponent kun til administrator
  • .
  • Kun bruger-komponent
  • Admin- og brugerkomponent
  • Generel brug af elementet
</header ); }

Komponenten har brug for to egenskaber. For det første børn ansvarlig for indhold, der er beskyttet. Den anden nødvendigeRoller at
håndterer en række roller, der giver os adgang.

Vi har brug for en repræsentation af denne struktur. Det er meget enkelt. Vi udvider typen React.PropsMedBørn der har børn
egenskab. Du kan selvfølgelig tilføje denne egenskab manuelt til din type og udelade udvidelsen.

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

Selve komponenten er også enkel. Vi vil genbruge harRolle funktion her.

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.børn}
        
    );
} ellers {
    return ;
}
}
"`

Og jeg kunne sige stop her, men det ville være for nemt. Nu har vi en komponent, og vi kan bruge den til det yderste 😀.

`GuardService`

Første skridt vil være eksternalisering af kontroller. nuværende bruger er en hardcoded værdi. Jeg vil gerne indkapsle denne værdi
til en tjeneste, der "ved", hvordan man verificerer roller. Teknisk set betyder det, at vi flytter harRolle funktion til en anden
klasse.

Jeg skaber en enkel grænseflade IGuardService der kun har én egenskab - harRolle.

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

En simpel implementering kunne se sådan ud

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

For at bruge det skal vi ændre IGuardEgenskaber og anvendelse.

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

// ...

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

Kun administrator-komponent
 

Kun bruger-komponent

Administrator- og brugerkomponent
 
 

Element til generel brug

 

);
}
```

Nu ser komponenten sådan ud:

 export const Guard = (props: IGuardProps) => {
     if (props.guardService.checkRole(props.requiredRoles)) {
         return (
             
                 {props.børn}
             
         );
     } ellers {
         return ;
     }
 }
 

Meget bedre. VagtService adskiller os fra den logik, der kontrollerer rollerne. Vi kan ændre det uden konsekvenser for vores
komponent. En almindelig brugssag er at bruge mock i tests og en "rigtig" implementering i produktionskoden.

Forbudt element

Næste forbedring bliver håndtering af brugerdefinerede Forbudt element. Den nuværende løsning gengiver et tomt element. Først er vi nødt til at
ændring IGuardProps tilføjer en funktion, der skal gengives for det pågældende element.

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

Dette er en valgfri egenskab, og navnet slutter med et spørgsmålstegn. Så det kan være en funktion eller udefineret. Vi er nødt til at
håndtere det i Vagt komponent.

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

{props.børn}

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

);
}
}

// ...

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

Kun administrator-komponent
 

Kun bruger-komponent

Forbudt - kun moderator kan se dette
}>
 

Moderator-komponent

 

Administrator- og brugerkomponent
 
 

Element til generel brug

 

);
}
```

Fleksibilitet i typer

Tid til den sidste store ændring. Den nuværende version af komponenten understøtter kun roller som streng. Vi kunne have flere forskellige
typer af egenskaber, som vi gerne vil kontrollere. Tal eller brugerdefinerede typer er ikke noget særligt. Jeg vil tilføje generisk understøttelse.

Første skridt er ændringer i IGuardService grænseflade. Implementeringer vil afhænge af typen af den testede værdi. Det kan være
være hvad som helst, så grænsefladen bør håndtere det.

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

Nu tager den et array af ROLLE generisk type. Vores enkle implementering vil ændre sig lidt.

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

Vi er nødt til at tilføje en typeparameter, men vi kan forberede en implementering, der understøtter IRole interface.

interface IRole {
navn: streng;
}

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

Andet trin er at udbrede denne ændring til IGuardProps.

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

Og henholdsvis til Vagt komponent.

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

Og vores brugsscenarier

export const AppHeader: FC = () =&gt; {
     const guardService = new SimpleGuard();
     const roleService = new RoleGuardService();
     return (
         <header>
             <nav>
                 <ul>
                     <Guard<IRole&gt; requiredRoles={[{name: "ADMIN"}]} guardService={roleService}&gt;.
                         <li>Komponent kun for administratorer</li>
                     </Guard>
                     <Guard<string&gt; requiredRoles={["USER"]} guardService={guardService}&gt;.
                         <li>Komponent kun for brugere</li>
                     </Guard>
                     <Guard<string&gt; requiredRoles={["MODERATOR"]} guardService={guardService}
                                    forbidden={() =&gt; <div>Forbudt - kun moderator kan se dette</div>}>
                         <li>Moderator-komponent</li>
                     </Guard>
                     <Guard<string&gt; requiredRoles={["USER", "ADMIN"]} guardService={guardService}&gt;.
                         <li>Administrator- og brugerkomponent</li>
                     </Guard>
                     <li>Generelt brugselement</li>
                 </ul>
             </nav>
         </header>
     );
 }

I dette eksempel bruger jeg begge implementeringer af IGuardservice bare til illustrative formål. I rigtige brugssager skal du
bruger sandsynligvis kun én.

Specialiserede komponenter og indlejring

Den Vagt kan være indlejret. Bare husk, at adgangen vil blive løst i rækkefølge fra den mest eksterne instans.

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>Komponent kun for administratorer</li>
                         </Guard>
                         <Guard<string&gt; requiredRoles={["USER"]} guardService={guardService}&gt;.
                             <li>Komponent kun for brugere</li>
                         </Guard>
                         <li>Administrator- og brugerkomponent</li>
                         <Guard<string&gt; requiredRoles={["MODERATOR"]} guardService={guardService}
                                        forbidden={() =&gt; <div>Forbudt - kun moderator kan se dette</div>}>
                             <li>Moderator-komponent</li>
                         </Guard>
                     </Guard>
                     <li>Generelt brugselement</li>
                 </ul>
             </nav>
         </header>
     );
 }

I ovenstående eksempel Moderator-komponent kunne aldrig vises, fordi brugeren kun kan håndtere én rolle. Den første Vagt grænser
roller til ADMIN og BRUGERså MODERATOR vil aldrig bestå første kontrol.

Vi kan bygge specialiserede komponenter, der skjuler nogle egenskaber.

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

}

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

Kun administrator-komponent
 

.
Kun bruger-komponent


Forbudt - kun moderator kan se dette
}>

Moderator-komponent

.

Administrator- og brugerkomponent

 

Element til generel brug

);
}
```

I dette tilfælde AdminGuard foruddefinerer ADMIN rolle. I konsekvenserne er vi nødt til eksplicit at definere typen af ROLLE type
parameter.

Opsummering

I denne artikel viser jeg dig, hvordan du opretter og bruger Vagt komponent i React. Vi starter med kompleks kode, der er svær at
læse og vedligeholde. Vi udvikler den til en mere udviklervenlig tilstand og introducerer brugerdefinerede funktionelle komponenter. Dernæst
udvide komponenten med ekstra funktioner, refaktorere udtrækningstjenesten og endelig tilføje generiske typer.

Endelig har vi en komponent, der kan indlejres, og som er nem at teste og vedligeholde.

Relaterede artikler

Udvikling af software

Fordele og ulemper ved React

Hvorfor er det værd at bruge React? Hvilke fordele har dette JavaScript-bibliotek? For at finde svarene skal du dykke ned i denne artikel og opdage de virkelige fordele ved at bruge React.

Codest
Cezary Goralski Software Engineer

Tilmeld dig vores vidensbase, og hold dig opdateret om ekspertisen fra it-sektoren.

    Om os

    The Codest - International softwareudviklingsvirksomhed med tech-hubs i Polen.

    Storbritannien - Hovedkvarter

    • Kontor 303B, 182-184 High Street North E6 2JA
      London, England

    Polen - Lokale teknologiske knudepunkter

    • Fabryczna Office Park, Aleja
      Pokoju 18, 31-564 Kraków
    • Hjerneambassaden, Konstruktorska
      11, 02-673 Warszawa, Polen

      Codest

    • Hjem
    • Om os
    • Serviceydelser
    • Casestudier
    • Ved hvordan
    • Karriere
    • Ordbog

      Serviceydelser

    • Det rådgivende
    • Udvikling af software
    • Backend-udvikling
    • Frontend-udvikling
    • Staff Augmentation
    • Backend-udviklere
    • Cloud-ingeniører
    • Dataingeniører
    • Andet
    • QA-ingeniører

      Ressourcer

    • Fakta og myter om at samarbejde med en ekstern softwareudviklingspartner
    • Fra USA til Europa: Hvorfor beslutter amerikanske startups sig for at flytte til Europa?
    • Sammenligning af Tech Offshore-udviklingsknudepunkter: Tech Offshore Europa (Polen), ASEAN (Filippinerne), Eurasien (Tyrkiet)
    • Hvad er de største udfordringer for CTO'er og CIO'er?
    • Codest
    • Codest
    • Codest
    • Privacy policy
    • Vilkår for brug af hjemmesiden

    Copyright © 2025 af The Codest. Alle rettigheder forbeholdes.

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