The Codest
  • Par mums
  • Pakalpojumi
    • Programmatūras izstrāde
      • Frontend izveide
      • Backend izstrāde
    • Staff Augmentation
      • Frontend izstrādātāji
      • Backend izstrādātāji
      • Datu inženieri
      • Mākoņa inženieri
      • QA inženieri
      • Citi
    • Tā Konsultatīvais dienests
      • Audits un konsultācijas
  • Nozares
    • Fintech un banku darbība
    • E-commerce
    • Adtech
    • Healthtech
    • Ražošana
    • Loģistika
    • Automobiļu nozare
    • IOT
  • Vērtība par
    • CEO
    • CTO
    • Piegādes vadītājs
  • Mūsu komanda
  • Case Studies
  • Zināt, kā
    • Blogs
    • Tikšanās
    • Tiešsaistes semināri
    • Resursi
Karjera Sazinieties ar mums
  • Par mums
  • Pakalpojumi
    • Programmatūras izstrāde
      • Frontend izveide
      • Backend izstrāde
    • Staff Augmentation
      • Frontend izstrādātāji
      • Backend izstrādātāji
      • Datu inženieri
      • Mākoņa inženieri
      • QA inženieri
      • Citi
    • Tā Konsultatīvais dienests
      • Audits un konsultācijas
  • Vērtība par
    • CEO
    • CTO
    • Piegādes vadītājs
  • Mūsu komanda
  • Case Studies
  • Zināt, kā
    • Blogs
    • Tikšanās
    • Tiešsaistes semināri
    • Resursi
Karjera Sazinieties ar mums
Atpakaļ bultiņa ATGRIEZTIES ATPAKAĻ
2023-05-19
Programmatūras izstrāde

Sastāvdaļu redzamība React ar nosacīto atveidošanu un aizsargiem

Bartlomiej Kuczynski

Uzziniet, kā vienkāršot un uzlabot komponentu redzamību programmā React, izmantojot nosacīto atveidošanu un aizsargkomponentus.

Šodien vēlos apspriest, kā kontrolēt komponenta redzamība React. Bet pirms mēs sākam ir mazs
atruna:

Prezentētais risinājums nav ļoti drošs, lai aizsargātu jūsu lietojumprogrammu pret "hakeriem" (lai kas tur būtu).
Atcerieties, ka jums ir jāaizsargā galapunkti un jāizmanto laba prakse lietojumprogrammu izstrādē. Šis risinājums tikai
nedaudz atvieglo jūsu darbu.

Uzdevums, problēmas risinājums vai tas, ko mēs vēlamies sasniegt.

Viena no visbiežāk sastopamajām funkcijām ir rādīt komponentu tikai vairākiem lietotājiem, kuriem ir noteiktas tiesības,
lomas vai privilēģijas. Parasts risinājums ir pievienot dažas jas uz kods, manuāli pārbaudiet nosacījumus un rādiet vai nerādiet elementus.

Ļaujiet apskatīt SimpleAppHeader komponents, kas satur dažus navigācijas elementus.

<!-- wp:paragraph -->
<p><code>tipscript jsx<br>
export const SimpleAppHeader: FC = () =&gt; {<br>
    return (<br>
        <header><br>
            <nav><br>
                <ul><br>
                    {<br>
                        currentUser.role === "ADMIN" &amp;&amp;&amp;<br>
                        <li>Tikai komponentsAdmin</li><br>
                    }<br>
                    {<br>
                        currentUser.role === "USER" &amp;&amp;<br>
                        <li>Tikai lietotāja komponents</li><br>
                    }<br>
                    {<br>
                        (currentUser.role === "ADMIN" || currentUser.role === "USER") &amp;&amp;<br>
                        <li>Tikai komponents "Administrator un lietotājs"</li><br>
                    }<br>
                    <li>Vispārējais lietošanas elements</li><br>
                </ul><br>
            </nav><br>
        </header><br>
    )<br>
}<br>
</code></p>
<!-- /wp:paragraph -->

Izskatās "nav slikti". Iespējams, lai samazinātu sarežģītību, pārbaudes varētu iekapsulēt funkcijās. currentUser ir kāds objekts
kas ir loma īpašība, bet tā var būt jebkas, ko mēs vēlamies izmantot kā kontroles mehānisma objektu.

Šim kodam ir dažas problēmas. Ja projekts aug mēs, iespējams, daudzviet lietojam šādas konstrukcijas. Tāpēc mums ir nepieciešams kopēt,
kaut kā, nosacījumi. Šo kodu ir grūti uzturēt un mainīt nākotnē. Īpaši tad, ja piekļuves noteikumi mainās
laiks, piemēram, mums ir jāmaina currentUser par kaut ko citu. To ir ļoti grūti pārbaudīt. Jums ir jāuzraksta daudzi testi.
lai pārbaudītu, vai jūsu stāvoklis ir kārtībā.

Vienkāršošana

Laiks nedaudz vienkāršot šo kodu. Mēs varētu izņemt dažas metodes un padarīt kodu īsāku un mazāk sarežģītu:

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) &&
Tikai administratora komponents

}
{
isUser(currentUser.role) &&

Tikai lietotāja komponents

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

Tikai administratora un lietotāja komponente

}

Vispārīgas lietošanas elements

)
}
```

Izskatās daudzsološi. Mēs samazinām troksni od atkārtot līnijas. Kods ir lasāmāks un vieglāk kopjams. Bet paskatieties uz
funkcija isAdminOrUser. Mums ir tikai divas lomas. Ja mēs ieviešam trešo lomu, mums ir jāizveido vēl viens funkciju kopums.
kas apvieno lomas. Laiks uz citu versiju.

Filtrēšana

Ļaujiet ieviest funkciju hasRole kas aizstās mūsu isX funkcijas.

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

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

{

hasRole(currentUser.role, ["ADMIN"]) &&
Tikai administratora komponents

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

Tikai lietotāja komponents

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

Tikai administratora un lietotāja komponente

}

Vispārīgas lietošanas elements

)
}
```

Tagad izskatās labi. Mums joprojām ir nosacījumi html koda daļā, bet tagad mēs varam testēt hasRole funkciju un uzticību, ka tā
tiks izmantots pareizs parametru kopums. Tagad ir vieglāk pievienot vai mainīt lomas. Mēs izmantojam masīvu, kas satur visus
lomas, kas mums ir nepieciešamas.

Tomēr šis risinājums ir saistīts ar currentUser objekts. Pieņēmums ir tāds, ka objekts ir globāls vai viegli pieejams.
jebkurā vietā lietojumprogrammā. Tāpēc mēs varam mēģināt to iekapsulēt. Protams, mēs to varam pārvietot uz hasRole funkcija:

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

Bet tas dod mums gandrīz nekas.

Portāls Sargs Sastāvdaļa

Laiks izveidot komponentu, kas iekapsulē visu loģiku. Es to nosaucu Sargs un es to gribu izmantot šādi.

 export const GuardedAppHeader: FC = () => {
     return (
         
  • Tikai komponente "Admin"
  • Tikai lietotāja komponente
  • Admin un lietotāja komponents
  • Vispārējās lietošanas elements
); }

Komponentam ir nepieciešamas divas īpašības. Pirmā bērni atbildīgs par saturu, kas tiek sargāts. Otrais requiredRoles ka
apstrādāt lomu masīvu, kas mums nodrošina piekļuvi.

Mums ir nepieciešama šīs struktūras reprezentācija. Tas ir ļoti vienkārši. Mēs paplašinām tipu React.Rekvizīti ar bērniem kas ir bērni
īpašums. Protams, varat manuāli pievienot šo īpašību savam tipam un izlaist paplašinājumu.

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

Arī pats komponents ir vienkāršs. Mēs atkārtoti izmantosim hasRole funkciju šeit.

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

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

Un es varētu teikt - apstājieties šeit, bet tas būtu pārāk vienkārši. Tagad mums ir komponents, un mēs to varam izmantot līdz galējībai 😀

`GuardService`

Pirmais solis būs pārbaužu eksternalizācija. currentUser ir cietā kodētā vērtība. Es gribētu šo vērtību iekapsulēt
kādā pakalpojumā, kas "zinās", kā pārbaudīt lomas. Tehniski tas nozīmē, ka mēs pārvietojam hasRole funkciju uz citu
klase.

Es izveidoju vienkāršu interfeisu IGuardService kam ir tikai viena īpašība - hasRole.

eksporta interfeiss IGuardService {
checkRole: (roles: string[]) => boolean;
}

Tagad vienkārša īstenošana varētu izskatīties šādi

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

Lai to izmantotu, mums ir jāmaina IGuardProperties un izmantošanas gadījums.

eksportēt interfeisu IGuardProps extends React.PropsWithChildren {
requiredRoles: string[];
guardService: IGuardService;
}

// ...

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

Tikai administratora komponente
 

Tikai lietotāja komponente

Administratora un lietotāja komponents
 
 

Vispārējās lietošanas elements

 

);
}
```

Tagad komponents izskatās šādi:

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

Daudz labāk. GuardService nošķir mūs no loģikas, kas pārbauda lomas. Mēs varam to mainīt bez sekām mūsu
sastāvdaļa. Bieži sastopams gadījums, kad testos tiek izmantota maketa, bet ražošanas kodā - "īsta" implementācija.

Aizliegts elements

Nākamais uzlabojums būs pielāgotu Aizliegts elements. Pašreizējais risinājums attēlo tukšu elementu. Vispirms mums ir nepieciešams
mainīt IGuardProps pievienojot funkciju, kas tiks atveidota šim elementam.

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

Šī ir izvēles īpašība, nosaukums beidzas ar jautājuma zīmes rakstzīmi. Tātad tā var būt funkcija vai nenoteikts. Mums ir nepieciešams
apstrādāt to Sargs sastāvdaļa.

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

{props.children}

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

);
}
}

// ...

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

Tikai administratora komponente
 

Tikai lietotāja komponente

Aizliegts - to var redzēt tikai moderators
}>
 

Moderatora komponents

 

Administratora un lietotāja komponents
 
 

Vispārējās lietošanas elements

 

);
}
```

Veidu elastība

Laiks pēdējām lielajām pārmaiņām. Pašreizējā versijā komponents atbalsta tikai šādas lomas virkne. Mums varētu būt vairāki dažādi
īpašumu veidi, kurus mēs vēlamies pārbaudīt. Skaitļi vai pielāgotie tipi nav nekas īpašs. Es pievienošu vispārīgu atbalstu.

Pirmais solis ir izmaiņas IGuardService saskarne. Implementācijas būs atkarīgas no pārbaudāmās vērtības tipa. To var
būt jebkas, tāpēc interfeisam vajadzētu to apstrādāt.

 eksportēt interfeisu IGuardService {
     checkRole: (roles: ROLE[]) => boolean;
 }

Tagad tas aizņem masīvu ROLE sugas tips. Mūsu vienkāršā implementācija nedaudz mainīsies.

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

Mums ir nepieciešams pievienot tipa parametru, bet mēs varētu sagatavot implementāciju, kas atbalsta IRole saskarne.

interfeiss IRole {
name: string;
}

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

Otrais solis ir šo izmaiņu izplatīšana IGuardProps.

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

Un attiecīgi uz Sargs sastāvdaļa.

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

Un mūsu lietošanas gadījumi

export const AppHeader: FC = () =&gt; {
     const guardService = new SimpleGuard();
     const roleService = new RoleGuardService();
     return (
         <header>
             <nav>
                 <ul>
                     <Guard<IRole&gt; requiredRoles={[{{nosaukums: "ADMIN"}]} guardService={roleService}&gt;
                         <li>Tikai administratora komponents</li>
                     </Guard>
                     <Guard<string&gt; requiredRoles={{["USER"]} guardService={GuardService}&gt;
                         <li>Tikai lietotāja komponents</li>
                     </Guard>
                     <Guard<string&gt; requiredRoles={{["MODERATOR"]} guardService={GuardService}
                                    aizliegts={() =&gt; <div>Aizliegts - tikai moderators to var redzēt</div>}>
                         <li>Moderatora komponents</li>
                     </Guard>
                     <Guard<string&gt; requiredRoles={{["USER", "ADMIN"]} guardService={GuardService}&gt;
                         <li>Administratora un lietotāja komponents</li>
                     </Guard>
                     <li>Vispārīgs izmantošanas elements</li>
                 </ul>
             </nav>
         </header>
     );
 }

Šajā piemērā es izmantoju abas implementācijas IGuardservice tikai ilustratīviem nolūkiem. Reālos lietošanas gadījumos jūs
iespējams, izmantot tikai vienu.

Specializēti komponenti un ligzdošana

Portāls Sargs varētu būt ligzdotas. Tikai atcerieties, ka piekļuve tiks atrisināta secībā no vairuma ārējo instanču.

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>Tikai administratora komponents</li>
                         </Guard>
                         <Guard<string&gt; requiredRoles={{["USER"]} guardService={GuardService}&gt;
                             <li>Tikai lietotāja komponents</li>
                         </Guard>
                         <li>Administratora un lietotāja komponents</li>
                         <Guard<string&gt; requiredRoles={{["MODERATOR"]} guardService={GuardService}
                                        aizliegts={() =&gt; <div>Aizliegts - tikai moderators to var redzēt</div>}>
                             <li>Moderatora komponents</li>
                         </Guard>
                     </Guard>
                     <li>Vispārīgs izmantošanas elements</li>
                 </ul>
             </nav>
         </header>
     );
 }

Iepriekš minētajā piemērā Moderatora komponents nekad nevarētu parādīties, jo lietotājs var rīkoties tikai ar vienu lomu. Pirmais Sargs ierobežojumi
lomas, lai ADMIN un LIETOTĀJS, tāpēc MODERATORS nekad neizturēs pirmo pārbaudi.

Varam izveidot specializētus komponentus, kas slēpj dažas īpašības.

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

}

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

Tikai administratora komponente
 


Tikai lietotāja komponente


Aizliegts - to var redzēt tikai moderators
}>

Moderatora komponents



Administratora un lietotāja komponente

 

Vispārējās lietošanas elements

);
}
```

Šajā gadījumā AdminGuard iepriekš definēt ADMIN loma. Sekās mums ir skaidri jādefinē tips ROLE tips
parametrs.

Apkopojiet

Šajā rakstā es parādīšu, kā izveidot un izmantot Sargs React komponents. Mēs sākam ar sarežģītu kodu, ko ir grūti
lasīt un uzturēt. Mēs attīstām to vairāk izstrādātājs draudzīgu stāvokli un ieviest pielāgotu funkcionālo komponentu. Tālāk mēs
paplašināt komponentu, pievienojot papildu funkcionalitātes, refaktorizēt pakalpojuma ieguvi un visbeidzot pievienot vispārīgos tipus.

Visbeidzot, mums ir komponents, ko var ievietot, ir viegli testēt un uzturēt.

Saistītie raksti

Programmatūras izstrāde

React plusi un mīnusi

Kāpēc ir vērts izmantot React? Kādas ir šīs JavaScript bibliotēkas priekšrocības? Lai uzzinātu atbildes, ieskatieties šajā rakstā un atklājiet reālās priekšrocības, ko sniedz React izmantošana.

The Codest
Cezary Goralski Software Engineer

Abonējiet mūsu zināšanu bāzi un saņemiet jaunāko informāciju par IT nozares pieredzi.

    Par mums

    The Codest - starptautisks programmatūras izstrādes uzņēmums ar tehnoloģiju centriem Polijā.

    Apvienotā Karaliste - Galvenā mītne

    • 303B birojs, 182-184 High Street North E6 2JA
      Londona, Anglija

    Polija - Vietējie tehnoloģiju centri

    • Fabryczna Office Park, Aleja
      Pokoju 18, 31-564 Krakova
    • Brain Embassy, Konstruktorska
      11, 02-673 Varšava, Polija

      The Codest

    • Sākums
    • Par mums
    • Pakalpojumi
    • Case Studies
    • Zināt, kā
    • Karjera
    • Vārdnīca

      Pakalpojumi

    • Tā Konsultatīvais dienests
    • Programmatūras izstrāde
    • Backend izstrāde
    • Frontend izveide
    • Staff Augmentation
    • Backend izstrādātāji
    • Mākoņa inženieri
    • Datu inženieri
    • Citi
    • QA inženieri

      Resursi

    • Fakti un mīti par sadarbību ar ārējo programmatūras izstrādes partneri
    • No ASV uz Eiropu: Kāpēc Amerikas jaunuzņēmumi nolemj pārcelties uz Eiropu?
    • Tehnoloģiju ārzonas attīstības centru salīdzinājums: Tech Offshore Eiropa (Polija), ASEAN (Filipīnas), Eirāzija (Turcija)
    • Kādi ir galvenie CTO un CIO izaicinājumi?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • Website terms of use

    Autortiesības © 2026 The Codest. Visas tiesības aizsargātas.

    lvLatvian
    en_USEnglish de_DEGerman sv_SESwedish da_DKDanish nb_NONorwegian fiFinnish fr_FRFrench pl_PLPolish arArabic it_ITItalian es_ESSpanish nl_NLDutch etEstonian elGreek pt_PTPortuguese cs_CZCzech lt_LTLithuanian lvLatvian