window.pipedriveLeadboosterConfig = { bas: 'leadbooster-chat.pipedrive.com', företagId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', version: 2, } ;(funktion () { var w = fönster if (w.LeadBooster) { console.warn('LeadBooster finns redan') } annars { w.LeadBooster = { q: [], on: funktion (n, h) { this.q.push({ t: "o", n: n, h: h }) }, trigger: funktion (n) { this.q.push({ t: 't', n: n }) }, } } })() Komponenters synlighet i React med villkorlig rendering och skydd - The Codest
Codest
  • Om oss
  • Tjänster
    • Utveckling av programvara
      • Frontend-utveckling
      • Backend-utveckling
    • Staff Augmentation
      • Frontend-utvecklare
      • Backend-utvecklare
      • Dataingenjörer
      • Ingenjörer inom molntjänster
      • QA-ingenjörer
      • Övriga
    • Det rådgivande
      • Revision och rådgivning
  • Industrier
    • Fintech & bankverksamhet
    • E-commerce
    • Adtech
    • Hälsoteknik
    • Tillverkning
    • Logistik
    • Fordon
    • IOT
  • Värde för
    • VD OCH KONCERNCHEF
    • CTO
    • Leveranschef
  • Vårt team
  • Fallstudier
  • Vet hur
    • Blogg
    • Möten
    • Webbinarier
    • Resurser
Karriär Ta kontakt med oss
  • Om oss
  • Tjänster
    • Utveckling av programvara
      • Frontend-utveckling
      • Backend-utveckling
    • Staff Augmentation
      • Frontend-utvecklare
      • Backend-utvecklare
      • Dataingenjörer
      • Ingenjörer inom molntjänster
      • QA-ingenjörer
      • Övriga
    • Det rådgivande
      • Revision och rådgivning
  • Värde för
    • VD OCH KONCERNCHEF
    • CTO
    • Leveranschef
  • Vårt team
  • Fallstudier
  • Vet hur
    • Blogg
    • Möten
    • Webbinarier
    • Resurser
Karriär Ta kontakt med oss
Pil tillbaka GÅ TILLBAKA
2023-05-19
Utveckling av programvara

Komponentens synlighet i React med villkorlig rendering och skydd

Bartlomiej Kuczynski

Lär dig hur du förenklar och förbättrar komponenternas synlighet i React med hjälp av villkorlig rendering och skyddskomponenter.

Idag skulle jag vilja diskutera hur man kan kontrollera komponentens synlighet i React. Men innan vi börjar finns det små
Ansvarsfriskrivning:

Den presenterade lösningen är inte särskilt säker när det gäller att skydda din applikation mot "hackare" (vilka de nu är).
Kom ihåg att du måste skydda dina slutpunkter och använda god praxis i applikationsdesignen. Den här lösningen gör bara
gör bara ditt arbete lite enklare.

Uppgift, problemlösning eller vad vi vill uppnå

En av de vanligaste funktionerna är att visa komponenter endast för ett antal användare som har vissa specifika rättigheter,
roller eller behörigheter. En vanlig lösning är att lägga till några oms till kod, manuellt kontrollera villkoren och visa eller inte element.

Låt oss ta en titt på SimpleAppHuvud komponent som innehåller få navigeringselement.

<!-- wp:paragraph -->
<p><code>typskript jsx<br>
export const SimpleAppHeader: FC = () =&gt; {<br>
    returnera (<br>
        <br>
            <nav><br>
                <ul><br>
                    {<br>
                        currentUser.role === "ADMIN" &amp;&amp;<br>
                        <li>Komponent endast för administratörer</li><br>
                    }<br>
                    {<br>
                        currentUser.role === "USER" &amp;&amp;<br>
                        <li>Enbart användarkomponent</li><br>
                    }<br>
                    }<br> {<br>
                        (currentUser.role === "ADMIN" || currentUser.role === "USER") &amp;&amp;<br>
                        <li>Enbart komponent för administratör och användare</li><br>
                    }<br>
                    <li>Generell användning av element</li><br>
                </ul><br>
            </nav><br>
        </header><br>
    )<br> <br>
}<br>
</code></p>
<!-- /wp:paragraph -->

Ser "inte illa" ut. Förmodligen kan du kapsla in kontroller i funktioner för att minska komplexiteten. Aktuell användare är något objekt
som har roll egendom, men det kan vara vad som helst som vi vill använda som föremål för vår kontrollmekanism.

Denna kod har vissa problem. Om projekt växer använder vi förmodligen dessa konstruktioner på många ställen. Så vi behöver kopiera,
på något sätt, villkor. Den här koden är svår att underhålla och ändra i framtiden. Speciellt när åtkomstreglerna ändras under
tid t.ex. vi behöver ändra Aktuell användare till något annat. Det är mycket svårt att testa. Du måste skriva många tester
bara för att verifiera om ditt tillstånd är ok.

Förenkling

Dags att förenkla den här koden lite. Vi kan extrahera några metoder och göra koden kortare och mindre komplex:

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

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

{

isAdmin(currentUser.role) &&
Endast Admin-komponent

}
{
isUser(currentUser.role) &&

Endast användarkomponent

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

Endast Admin- och User-komponent

}

Element för allmän användning

)
}
```

Det ser lovande ut. Vi minskar brus och upprepade rader. Koden blir mer läsbar och lättare att underhålla. Men ta en titt på
funktion isAdminOrUser. Vi har bara två roller. Om vi inför en tredje roll måste vi skapa en annan uppsättning funktioner
som kombinerar roller. Dags för en ny version.

Filtrering

Låt införa funktionen harRoll som kommer att vara ersättning för vår isX funktioner.

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

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

{

hasRole(currentUser.role, ["ADMIN"]) &&
Endast Admin-komponent

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

Endast användarkomponent

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

Endast Admin- och User-komponent

}

Element för allmän användning

)
}
```

Nu ser det bra ut. Vi har fortfarande villkor i html-delen av koden, men nu kan vi testa harRoll funktion och lita på att den
kommer att användas med rätt uppsättning parametrar. Det är nu enklare att lägga till eller ändra roller. Vi använder en array som innehåller alla
roller som vi behöver ha på plats.

Denna lösning är dock bunden till Aktuell användare objekt. Antagandet är att objektet på något sätt är globalt eller lättillgängligt i
var som helst i applikationen. Så vi kan försöka kapsla in det här. Naturligtvis kan vi flytta den till harRoll funktion:

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

Men det ger oss nästan ingenting.

Den Vakt Komponent

Dags att skapa en komponent som kapslar in hela logiken. Jag döpte den till Vakt och det är så här jag vill använda den.

 export const GuardedAppHeader: FC = () => {
     returnera (
          
             
    • Komponent endast för administratörer
    • Enbart användarkomponent
    • .
    • Admin- och användarkomponent
    • Generell användning av elementet
</header ); }

Komponent behöver två egenskaper. För det första barn ansvarig för innehåll som är skyddat. Andra nödvändigaRoller att
hantera en rad olika roller som ger oss tillgång.

Vi behöver en representation av denna struktur. Det är mycket enkelt. Vi utökar typen React.RekvisitaMedBarn som har barn
egenskap. Naturligtvis kan du manuellt lägga till den egenskapen i din typ och utelämna extension.

interface IGuardProps extends React.PropsWithChildren {
requiredRoles: sträng[];
}

Själva komponenten är också enkel. Vi kommer att återanvända harRoll funktion här.

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}
        
    );
} annars {
    returnera ;
}
}
"`

Och jag skulle kunna säga stopp här, men det skulle vara för lätt. Nu har vi en komponent och vi kan använda den till det yttersta 😀.

`GuardService`

Första steget blir att externalisera kontrollerna. Aktuell användare är ett hårdkodat värde. Jag skulle vilja kapsla in detta värde
till någon tjänst som "vet" hur man verifierar roller. Tekniskt sett innebär det att vi flyttar harRoll funktion till en annan
klass.

Jag skapar ett enkelt gränssnitt IGuardService som bara har en egenskap - harRoll.

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

Nu kan en enkel implementering se ut så här

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

För att använda den måste vi ändra IGuardEgenskaper och användningsområde.

export interface IGuardProps extends React.PropsWithChildren {
requiredRoles: sträng[];
vaktService: IGuardService;
}

// ...

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

Endast Admin-komponent
 

Endast användarkomponent

Admin- och användarkomponent
 
 

Element för allmän användning

 

);
}
```

Nu ser komponenten ut som:

 export const Guard = (props: IGuardProps) => {
     if (props.guardService.checkRole(props.requiredRoles)) {
         return (
             
                 {props.barn}
             
         );
     } annars {
         returnera ;
     }
 }
 

Mycket bättre. Vakttjänst separera oss från logik som kontrollerar roller. Vi kan ändra det utan konsekvenser för vår
komponent. Ett vanligt användningsfall är att använda mock i tester och viss "riktig" implementering i produktionskoden.

Förbjudet element

Nästa förbättring kommer att vara hantering av anpassade Förbjudet element. Den nuvarande lösningen återger ett tomt element. Först måste vi
förändring IGuardProps lägger till funktion som kommer att renderas för det elementet.

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

Detta är en valfri egenskap, namnet slutar med ett frågetecken. Så det kan vara funktion eller odefinierad. Vi behöver
hantera det i Vakt komponent.

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

{props.barn}

);
} else if (props.forbidden === undefined) {
returnera ;
} annars {
returnera (
{rekvisita.förbjuden()}

);
}
}

// ...

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

Endast Admin-komponent
 

Endast användarkomponent

Förbjuden - endast moderator kan se detta
}>
 

Moderator-komponent

 

Admin- och användarkomponent
 
 

Element för allmän användning

 

);
}
```

Flexibilitet av typer

Dags för den sista stora förändringen. Nuvarande version av komponenten stöder endast roller som sträng. Vi skulle kunna ha flera olika
typer av egendom som vi vill kontrollera. Siffror eller anpassade typer är inget speciellt. Jag kommer att lägga till generiskt stöd.

Första steget är förändringar i IGuardService gränssnitt. Implementationerna beror på vilken typ av värde som testas. Det kan vara
kan vara vad som helst, så gränssnittet bör hantera det.

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

Nu tar den en matris av ROLL generisk typ. Vår enkla implementering kommer att förändras lite.

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

Vi måste lägga till en typparameter, men vi kan förbereda en implementation som stöder IRole gränssnitt.

gränssnitt IRole {
namn: sträng;
}

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

Andra steget är att sprida denna ändring till IGuardProps.

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

Och respektive till Vakt komponent.

export const Guard = (props: IGuardProps) => {
     if (props.guardService.checkRole(props.requiredRoles)) {
         return (
             
                 {props.barn}
             
         );
     } else if (props.forbidden === undefined) {
         returnera ;
     } annars {
         returnera (
                 {rekvisita.förbjuden()}
             
         );
     }
 }

Och våra användningsområden

export const AppHeader: FC = () =&gt; {
     const guardService = ny SimpleGuard();
     const roleService = new RoleGuardService();
     return (
         <header>
             <nav>
                 <ul>
                     <Guard<IRole&gt; requiredRoles={[{namn: "ADMIN"}]} guardService={roleService}&gt;
                         <li>Komponent endast för administratörer</li>
                     </Guard>
                     <Guard<string&gt; requiredRoles={["USER"]} guardService={guardService}&gt;
                         <li>Endast användarkomponent</li>
                     </Guard>
                     <Guard<string&gt; requiredRoles={["MODERATOR"]} guardService={guardService}
                                    förbjudet={() =&gt; <div>Förbjudet - endast moderator kan se detta</div>}>
                         <li>Moderatorkomponent</li>
                     </Guard>
                     <Guard<string&gt; requiredRoles={["USER", "ADMIN"]} guardService={guardService}&gt;
                         <li>Admin- och användarkomponent</li>
                     </Guard>
                     <li>Allmänt användningselement</li>
                 </ul>
             </nav>
         </header>
     );
 }

I det här exemplet använder jag båda implementationerna av IGuardservice bara för illustrativa ändamål. I verkliga användningsfall kan du
förmodligen bara använda en.

Specialiserade komponenter och inbyggnad

Den Vakt kan vara nästlade. Kom bara ihåg att åtkomst kommer att lösas i ordning från den mest externa instansen.

export const NestAppHeader: FC = () =&gt; {
     const guardService = new SimpleGuard();
     returnera (
         <header>
             <nav>
                 <ul>
                     <Guard<string&gt; requiredRoles={["USER", "ADMIN"]} guardService={guardService}&gt;
                         <Guard<string&gt; requiredRoles={["ADMIN"]} guardService={guardService}&gt;
                             <li>Komponent endast för administratörer</li>
                         </Guard>
                         <Guard<string&gt; requiredRoles={["USER"]} guardService={guardService}&gt;
                             <li>Endast användarkomponent</li>
                         </Guard>
                         <li>Admin- och användarkomponent</li>
                         <Guard<string&gt; requiredRoles={["MODERATOR"]} guardService={guardService}
                                        förbjudet={() =&gt; <div>Förbjudet - endast moderator kan se detta</div>}>
                             <li>Moderatorkomponent</li>
                         </Guard>
                     </Guard>
                     <li>Allmänt användningselement</li>
                 </ul>
             </nav>
         </header>
     );
 }

I ovanstående exempel Moderatorkomponent skulle aldrig kunna dyka upp, eftersom användaren bara kan hantera en roll. Första Vakt gränser
roller till ADMIN och ANVÄNDARE, så MODERATOR kommer aldrig att passera första kontrollen.

Vi kan bygga specialiserade komponenter som döljer vissa egenskaper.

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

}

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

Endast Admin-komponent
 


Endast användarkomponent


Förbjudet - endast moderator kan se detta
}>

Moderator-komponent



Admin- och användarkomponent

 

Element för allmän användning

);
}
```

I detta fall AdminGuard fördefiniera ADMIN roll. Som en följd av detta måste vi uttryckligen definiera typen av ROLL typ
parameter.

Sammanfatta

I den här artikeln visar jag dig hur du skapar och använder Vakt komponent i React. Vi utgår från komplex kod som är svår att förstå och
läsa och underhålla. Vi utvecklar det till ett mer utvecklarvänligt tillstånd och introducerar anpassade funktionella komponenter. Nästa steg är
utöka komponenten med extra funktioner, omarbeta extraheringstjänsten och slutligen lägga till generiska typer.

Slutligen har vi en komponent som kan nästlas och som är lätt att testa och underhålla.

Relaterade artiklar

Utveckling av programvara

För- och nackdelar med React

Varför är det värt att använda React? Vilka fördelar har detta JavaScript-bibliotek? För att ta reda på svaren dyk in i den här artikeln och upptäck de verkliga fördelarna med att använda React.

Codest
Cezary Goralski Software Engineer

Prenumerera på vår kunskapsbas och håll dig uppdaterad om expertisen från IT-sektorn.

    Om oss

    The Codest - Internationellt mjukvaruutvecklingsföretag med teknikhubbar i Polen.

    Förenade kungariket - Huvudkontor

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

    Polen - Lokala tekniknav

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

      Codest

    • Hem
    • Om oss
    • Tjänster
    • Fallstudier
    • Vet hur
    • Karriär
    • Ordbok

      Tjänster

    • Det rådgivande
    • Utveckling av programvara
    • Backend-utveckling
    • Frontend-utveckling
    • Staff Augmentation
    • Backend-utvecklare
    • Ingenjörer inom molntjänster
    • Dataingenjörer
    • Övriga
    • QA-ingenjörer

      Resurser

    • Fakta och myter om att samarbeta med en extern partner för mjukvaruutveckling
    • Från USA till Europa: Varför väljer amerikanska startup-företag att flytta till Europa?
    • Jämförelse av Tech Offshore Development Hubs: Tech Offshore Europa (Polen), ASEAN (Filippinerna), Eurasien (Turkiet)
    • Vilka är de största utmaningarna för CTO:er och CIO:er?
    • Codest
    • Codest
    • Codest
    • Privacy policy
    • Användarvillkor för webbplatsen

    Copyright © 2025 av The Codest. Alla rättigheter reserverade.

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