window.pipedriveLeadboosterConfig = { base: 'leadbooster-chat.pipedrive.com', companyId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', versjon: 2, } ;(function () { var w = vindu if (w.LeadBooster) { console.warn('LeadBooster finnes 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 }) }, } } })() Komponentsynlighet i React med betinget gjengivelse og vakter - The Codest
The Codest
  • Om oss
  • Tjenester
    • Programvareutvikling
      • Frontend-utvikling
      • Backend-utvikling
    • Staff Augmentation
      • Frontend-utviklere
      • Backend-utviklere
      • Dataingeniører
      • Ingeniører i skyen
      • QA-ingeniører
      • Annet
    • Det rådgivende
      • Revisjon og rådgivning
  • Industrier
    • Fintech og bankvirksomhet
    • E-commerce
    • Adtech
    • Helseteknologi
    • Produksjon
    • Logistikk
    • Bilindustrien
    • IOT
  • Verdi for
    • ADMINISTRERENDE DIREKTØR
    • CTO
    • Leveransesjef
  • Vårt team
  • Casestudier
  • Vet hvordan
    • Blogg
    • Møter
    • Webinarer
    • Ressurser
Karriere Ta kontakt med oss
  • Om oss
  • Tjenester
    • Programvareutvikling
      • Frontend-utvikling
      • Backend-utvikling
    • Staff Augmentation
      • Frontend-utviklere
      • Backend-utviklere
      • Dataingeniører
      • Ingeniører i skyen
      • QA-ingeniører
      • Annet
    • Det rådgivende
      • Revisjon og rådgivning
  • Verdi for
    • ADMINISTRERENDE DIREKTØR
    • CTO
    • Leveransesjef
  • Vårt team
  • Casestudier
  • Vet hvordan
    • Blogg
    • Møter
    • Webinarer
    • Ressurser
Karriere Ta kontakt med oss
Pil tilbake GÅ TILBAKE
2023-05-19
Programvareutvikling

Komponentsynlighet i React med betinget gjengivelse og vakter

Bartlomiej Kuczynski

Lær hvordan du kan forenkle og forbedre komponentsynligheten i React ved hjelp av betinget gjengivelse og beskyttelseskomponenter.

I dag vil jeg gjerne diskutere hvordan man kan kontrollere komponentens synlighet i React. Men før vi begynner er det en liten
Ansvarsfraskrivelse:

Den presenterte løsningen er ikke særlig sikker når det gjelder å beskytte applikasjonen mot "hackere" (hvem det nå enn er).
Husk at du må beskytte endepunktene dine og bruke god praksis i applikasjonsdesign. Denne løsningen gjør bare
gjør bare arbeidet ditt litt enklere.

Oppgave, problemløsning eller hva vi ønsker å oppnå

En av de vanligste funksjonene er å vise komponenter kun for en gruppe brukere som har bestemte rettigheter,
roller eller rettigheter. En vanlig løsning er å legge til noen hviss til kode, sjekk forholdene manuelt og vis eller ikke elementer.

La oss ta en titt på SimpleAppHeader komponent som inneholder få navigasjonselementer.

<!-- 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>Bare administrator-komponent</li><br>
                    }<br><br>
                    {<br>
                        currentUser.role === "USER" &amp;&amp;<br> <li>Bare brukerkomponent</li><br>
                        <li>Bare brukerkomponent</li><br> }<br> {<br> currentUser.role === "USER" &amp;&amp;<li><br>
                    }<br>
                    {<br>
                        (currentUser.role === "ADMIN" || currentUser.role === "USER") &amp;&amp;<br>
                        <li>Komponent kun for administrator og bruker</li><br> }<br> {<br> (currentUser.
                    }<br><br>
                    <li>Generell bruk av elementet</li><br>
                </ul><br> </ul><br>
            </nav><br>
        </header><br>
    )<br> <br>
}<br><br>
</code></p>
<!-- /wp:paragraph -->

Ser "ikke så verst" ut. Sannsynligvis kan du kapsle sjekkene inn i funksjoner for å redusere kompleksiteten. nåværendeBruker er et objekt
som har rolle egenskap, men det kan være hva som helst som vi ønsker å bruke som gjenstand for kontrollmekanismen vår.

Denne koden har noen problemer. Hvis prosjekt vokser, bruker vi sannsynligvis den konstruksjonen mange steder. Så vi må kopiere,
på en eller annen måte, betingelser. Denne koden er vanskelig å vedlikeholde og endre i fremtiden. Spesielt når tilgangsreglene endres i løpet av
tid, f.eks. må vi endre nåværendeBruker til noe annet. Det er veldig vanskelig å teste. Du må skrive mange tester
bare for å sjekke om tilstanden din er ok.

Forenkling

På tide å forenkle denne koden litt. Vi kan trekke ut noen metoder og gjø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 Admin-komponent

}
{
isUser(currentUser.role) &&

Kun bruker-komponent

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

Kun Admin- og brukerkomponent

}

Element for generell bruk

)
}
```

Det ser lovende ut. Vi reduserer støy og gjentatte linjer. Koden er mer lesbar og enklere å vedlikeholde. Men ta en titt på
funksjon isAdminOrUser. Vi har bare to roller. Hvis vi innfører en tredje rolle, må vi opprette et nytt sett med funksjoner
som kombinerer roller. På tide med en ny versjon.

Filtrering

La oss introdusere funksjonen hasRole som vil være en erstatning for vår isX funksjoner.

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 Admin-komponent

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

Kun bruker-komponent

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

Kun Admin- og User-komponent

}

Element for generell bruk

)
}
```

Nå ser det bra ut. Vi har fortsatt betingelser i html-delen av koden, men nå kan vi teste hasRole funksjon og stoler på at den
vil bli brukt med riktig sett med parametere. Det er nå enklere å legge til eller endre roller. Vi bruker en matrise som inneholder alle
roller som vi trenger på plass.

Denne løsningen er imidlertid bundet til nåværendeBruker objekt. Forutsetningen er at objektet på en eller annen måte er globalt eller lett tilgjengelig i
et hvilket som helst sted i applikasjonen. Så vi kan prøve å innkapsle dette. Vi kan selvfølgelig flytte den til hasRole funksjon:

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

Men det gir oss nesten ingenting.

Den Vakt Komponent

På tide å lage en komponent som kapsler inn hele logikken. Jeg kalte den Vakt og det er slik jeg vil bruke den.

 export const GuardedAppHeader: FC = () => {
     return (
         
    • Komponent kun for administrator
    • Bare brukerkomponent
    • Bare brukerkomponent
    • Admin- og brukerkomponent
    • Admin- og brukerkomponent
    • Generell bruk av elementet
</header ); }

Komponent trenger to egenskaper. For det første barn ansvarlig for innhold som er beskyttet. Andre requiredRoles at
håndtere en rekke roller som gir oss tilgang.

Vi trenger en representasjon av denne strukturen. Det er veldig enkelt. Vi utvider typen React.rekvisittermedbarn som har barn
egenskapen. Du kan selvfølgelig legge til denne egenskapen manuelt i typen og utelate utvidelsen.

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

Selve komponenten er også enkel. Vi vil gjenbruke hasRole funksjon 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.barn}
        
    );
} ellers {
    return ;
}
}
"`

Og jeg kunne sagt stopp her, men det ville blitt for enkelt. Nå har vi komponenten, og vi kan bruke den til det ytterste 😀.

`GuardService`

Første skritt vil være eksternalisering av kontroller. nåværendeBruker er en hardkodet verdi. Jeg vil gjerne innkapsle denne verdien
til en tjeneste som "vet" hvordan rollene skal verifiseres. Teknisk sett betyr det at vi flytter hasRole funksjon til en annen
klasse.

Jeg lager et enkelt grensesnitt IGuardService som bare har én egenskap - hasRole.

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

Nå kan en enkel implementering se slik ut

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

For å bruke den må vi endre IGuardEgenskaper og brukstilfelle.

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

// ...

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

Kun administrator-komponent
 

Kun brukerkomponent

Admin- og brukerkomponent
 
 

Element for generell bruk

 

);
}
```

Nå ser komponenten slik ut:

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

Mye bedre. GuardService skiller oss fra logikken som kontrollerer rollene. Vi kan endre den uten at det får konsekvenser for vår
komponent. Det er vanlig å bruke mock i tester og en "ekte" implementering i produksjonskoden.

Forbudt element

Neste forbedring vil være håndtering av egendefinerte Forbudt element. Den nåværende løsningen gjengir et tomt element. Først må vi
endring IGuardProps legge til funksjon som vil bli gjengitt det elementet.

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

Dette er en valgfri egenskap, og navnet slutter med et spørsmålstegn. Så det kan være funksjon eller udefinert. Vi trenger å
håndtere det i Vakt komponent.

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

{props.children}

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

);
}
}

// ...

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

Kun administrator-komponent
 

Kun brukerkomponent

Forbudt - bare moderator kan se dette
}>
 

Moderator-komponent

 

Administrator- og brukerkomponent
 
 

Element for generell bruk

 

);
}
```

Fleksibilitet i typer

På tide med den siste store endringen. Nåværende versjon av komponenten støtter kun roller som streng. Vi kan ha flere forskjellige
typer egenskaper som vi ønsker å sjekke. Tall eller egendefinerte typer er ikke noe spesielt. Jeg vil legge til generisk støtte.

Første skritt er endringer i IGuardService grensesnitt. Implementeringene vil avhenge av typen testet verdi. Det kan
være hva som helst, så grensesnittet bør håndtere det.

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

Nå tar den en matrise av ROLLE generisk type. Vår enkle implementering vil endre seg litt.

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

Vi må legge til en typeparameter, men vi kan forberede en implementering som støtter IRole grensesnitt.

grensesnitt IRole {
navn: string;
}

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

Det andre trinnet er å videreføre denne endringen til IGuardProps.

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

Og henholdsvis til Vakt komponent.

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

Og brukstilfellene våre

export const AppHeader: FC = () =&gt; {
     const guardService = new SimpleGuard();
     const roleService = new RoleGuardService();
     return (
         <header>
             <nav>
                 <ul>
                     <Guard<IRole&gt; requiredRoles={[{navn: "ADMIN"}]} guardService={roleService}&gt;
                         <li>Kun administrator-komponent</li>
                     </Guard>
                     <Guard<string&gt; requiredRoles={["USER"]} guardService={guardService}&gt;
                         <li>Kun brukerkomponent</li>
                     </Guard>
                     <Guard<string&gt; requiredRoles={["MODERATOR"]} guardService={guardService}
                                    forbidden={() =&gt; <div>Forbudt - bare moderator kan se dette</div>}>
                         <li>Moderatorkomponent</li>
                     </Guard>
                     <Guard<string&gt; requiredRoles={[["USER", "ADMIN"]} guardService={guardService}&gt;.
                         <li>Administrator- og brukerkomponent</li>
                     </Guard>
                     <li>Generelt brukselement</li>
                 </ul>
             </nav>
         </header>
     );
 }

I dette eksempelet bruker jeg begge implementasjonene av IGuardservice bare for illustrasjonsformål. I reelle brukstilfeller må du
sannsynligvis bare bruke én.

Spesialiserte komponenter og nesting

Den Vakt kan være nestet. Bare husk at tilgang vil bli løst i rekkefølge fra den mest eksterne instansen.

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>Kun administrator-komponent</li>
                         </Guard>
                         <Guard<string&gt; requiredRoles={["USER"]} guardService={guardService}&gt;
                             <li>Kun brukerkomponent</li>
                         </Guard>
                         <li>Administrator- og brukerkomponent</li>
                         <Guard<string&gt; requiredRoles={["MODERATOR"]} guardService={guardService}
                                        forbidden={() =&gt; <div>Forbudt - bare moderator kan se dette</div>}>
                             <li>Moderatorkomponent</li>
                         </Guard>
                     </Guard>
                     <li>Generelt brukselement</li>
                 </ul>
             </nav>
         </header>
     );
 }

I eksempelet ovenfor Moderatorkomponent aldri kunne vises, fordi brukeren bare kan håndtere én rolle. Første Vakt grenser
roller til ADMIN og BRUKER, så MODERATOR vil aldri passere første sjekk.

Vi kan bygge spesialiserte komponenter som skjuler enkelte egenskaper.

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

}

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

Kun administrator-komponent
 


Kun brukerkomponent


Forbudt - bare moderator kan se dette
}>

Moderator-komponent



Administrator- og brukerkomponent

 

Element for generell bruk

);
}
```

I dette tilfellet AdminGuard forhåndsdefinere ADMIN rolle. Som en konsekvens av dette må vi eksplisitt definere typen ROLLE type
parameter.

Oppsummering

I denne artikkelen viser jeg deg hvordan du oppretter og bruker Vakt komponent i React. Vi tar utgangspunkt i kompleks kode som er vanskelig å
lese og vedlikeholde. Vi utvikler den til en mer utviklervennlig tilstand og introduserer tilpassede funksjonelle komponenter. Deretter
utvide komponenten med ekstra funksjonalitet, refaktorere uttrekkstjenesten og til slutt legge til generiske typer.

Til slutt har vi en komponent som kan nestes, og som er enkel å teste og vedlikeholde.

Relaterte artikler

Programvareutvikling

Fordeler og ulemper med React

Hvorfor er det verdt å bruke React? Hvilke fordeler har dette JavaScript-biblioteket? For å finne svarene kan du dykke ned i denne artikkelen og oppdage de virkelige fordelene ved å bruke React.

The Codest
Cezary Goralski Software Engineer

Abonner på vår kunnskapsbase og hold deg oppdatert på ekspertisen fra IT-sektoren.

    Om oss

    The Codest - Internasjonalt programvareutviklingsselskap med teknologisentre i Polen.

    Storbritannia - Hovedkvarter

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

    Polen - Lokale teknologisentre

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

      The Codest

    • Hjem
    • Om oss
    • Tjenester
    • Casestudier
    • Vet hvordan
    • Karriere
    • Ordbok

      Tjenester

    • Det rådgivende
    • Programvareutvikling
    • Backend-utvikling
    • Frontend-utvikling
    • Staff Augmentation
    • Backend-utviklere
    • Ingeniører i skyen
    • Dataingeniører
    • Annet
    • QA-ingeniører

      Ressurser

    • Fakta og myter om samarbeid med en ekstern programvareutviklingspartner
    • Fra USA til Europa: Hvorfor velger amerikanske oppstartsbedrifter å flytte til Europa?
    • Sammenligning av Tech Offshore Development Hubs: Tech Offshore Europa (Polen), ASEAN (Filippinene), Eurasia (Tyrkia)
    • Hva er de største utfordringene for CTO-er og CIO-er?
    • The Codest
    • The Codest
    • The Codest
    • Retningslinjer for personver
    • Vilkår for bruk av nettstedet

    Opphavsrett © 2025 av The Codest. Alle rettigheter forbeholdt.

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