window.pipedriveLeadboosterConfig = { base: pipedrive.com', companyId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', version: 2, } ;(function () { var w = window if (w.LeadBooster) { console.warn('LeadBooster on jo olemassa') } 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 }) }, } } })() Komponenttien näkyvyys React:ssä ehdollisen renderöinnin ja suojien avulla - The Codest
Codest
  • Tietoa meistä
  • Palvelut
    • Ohjelmistokehitys
      • Frontend-kehitys
      • Backend-kehitys
    • Staff Augmentation
      • Frontend-kehittäjät
      • Backend-kehittäjät
      • Tietoinsinöörit
      • Pilvi-insinöörit
      • QA insinöörit
      • Muut
    • Se neuvoa-antava
      • Tilintarkastus & konsultointi
  • Toimialat
    • Fintech & pankkitoiminta
    • E-commerce
    • Adtech
    • Terveysteknologia
    • Valmistus
    • Logistiikka
    • Autoteollisuus
    • IOT
  • Arvo
    • TOIMITUSJOHTAJA
    • CTO
    • Toimituspäällikkö
  • Tiimimme
  • Tapaustutkimukset
  • Tiedä miten
    • Blogi
    • Tapaamiset
    • Webinaarit
    • Resurssit
Työurat Ota yhteyttä
  • Tietoa meistä
  • Palvelut
    • Ohjelmistokehitys
      • Frontend-kehitys
      • Backend-kehitys
    • Staff Augmentation
      • Frontend-kehittäjät
      • Backend-kehittäjät
      • Tietoinsinöörit
      • Pilvi-insinöörit
      • QA insinöörit
      • Muut
    • Se neuvoa-antava
      • Tilintarkastus & konsultointi
  • Arvo
    • TOIMITUSJOHTAJA
    • CTO
    • Toimituspäällikkö
  • Tiimimme
  • Tapaustutkimukset
  • Tiedä miten
    • Blogi
    • Tapaamiset
    • Webinaarit
    • Resurssit
Työurat Ota yhteyttä
Takaisin nuoli PALAA TAAKSE
2023-05-19
Ohjelmistokehitys

Komponenttien näkyvyys React:ssä ehdollisen renderöinnin ja suojien avulla

Bartlomiej Kuczynski

Opi yksinkertaistamaan ja parantamaan komponenttien näkyvyyttä React:ssä käyttämällä ehdollista renderöintiä ja suojauskomponentteja.

Tänään haluaisin keskustella siitä, miten hallita komponenttien näkyvyys React:ssä. Mutta ennen kuin aloitamme on pieni
vastuuvapauslauseke:

Esitelty ratkaisu ei ole kovin turvallinen, sillä se ei suojaa sovellusta "hakkereilta" (joita sitten onkin).
Muista, että sinun on suojattava päätepisteet ja käytettävä hyviä käytäntöjä sovellussuunnittelussa. Tämä ratkaisu vain
tekee työstäsi vain hieman helpompaa.

Tehtävä, ongelmanratkaisu tai se, mitä haluamme saavuttaa.

Yksi yleisimmistä toiminnoista on näyttää komponentti vain tietyille käyttäjille, joilla on tietyt oikeudet,
roolit tai oikeudet. Yleinen ratkaisu on lisätä joitakin joss:lle koodi, tarkista olosuhteet manuaalisesti ja näytä tai jätä elementit näyttämättä.

Katsotaanpa SimpleAppHeader komponentti, joka sisältää vain vähän navigointielementtejä.

<!-- 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>VainAdmin-komponentti</li><br>
                    }<br>
                    {<br>
                        currentUser.role === "USER" &amp;&amp;<br>
                        <li>Ainoastaan käyttäjäkomponentti</li><br>
                    }<br>
                    {<br>
                        (currentUser.role === "ADMIN" || currentUser.role === "USER") &amp;&amp;<br>
                        <li>VainAdmin- ja User-komponentti</li><br>
                    }<br>
                    <li>Yleinen käyttöelementti</li><br>
                </ul><br>
            </nav><br>
        </header><br>
    )<br>
}<br>
</code></p>
<!-- /wp:paragraph -->

Näyttää "ihan hyvältä". Todennäköisesti tarkistukset voitaisiin kapseloida funktioihin monimutkaisuuden vähentämiseksi. currentUser on jokin objekti
joka on rooli ominaisuus, mutta se voi olla mikä tahansa, jota haluamme käyttää valvontamekanismimme kohteena.

Tässä koodissa on joitakin ongelmia. Jos projekti kasvaa käytämme luultavasti tätä rakennetta monissa paikoissa. Meidän on siis kopioitava,
jotenkin, olosuhteissa. Tätä koodia on vaikea ylläpitää ja muuttaa tulevaisuudessa. Varsinkin kun pääsysäännöt muuttuvat
aika esim. meidän on muutettava currentUser joksikin muuksi. Sitä on hyvin vaikea testata. Sinun täytyy kirjoittaa monia testejä
vain varmistaaksesi, että tilasi on kunnossa.

Yksinkertaistaminen

On aika yksinkertaistaa tätä koodia hieman. Voisimme poimia joitakin metodeja ja tehdä koodista lyhyemmän ja vähemmän monimutkaisen:

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

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

{

isAdmin(currentUser.role) &&
Vain admin-komponentti

}
{
isUser(currentUser.role) &&

Vain käyttäjä-komponentti

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

Vain järjestelmänvalvojan ja käyttäjän komponentti

}

Yleinen käyttöelementti

)
}
```

Näyttää lupaavalta. Vähennämme melua od toista rivejä. Koodi on luettavampaa ja helpompi ylläpitää. Mutta katsokaa
toiminto isAdminOrUser. Meillä on vain kaksi roolia. Jos otamme käyttöön kolmannen roolin, meidän on luotava toinen joukko toimintoja.
joka yhdistää rooleja. Aika toiseen versioon.

Suodatus

Otetaan käyttöön funktio hasRole joka korvaa meidän isX toiminnot.

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"]) &&
Vain admin-komponentti

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

Vain käyttäjä-komponentti

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

Vain admin- ja user-komponentti

}

Yleinen käyttöelementti

)
}
```

Nyt näyttää hyvältä. Meillä on edelleen ehtoja html-koodin osassa, mutta nyt voimme testata seuraavia asioita. hasRole toiminto ja luottaa siihen, että se
käytetään oikeilla parametreilla. Roolien lisääminen tai muuttaminen on nyt helpompaa. Käytämme arraya, joka sisältää kaikki
roolit, joita tarvitsemme.

Tämä ratkaisu on kuitenkin sidottu currentUser esine. Oletuksena on, että objekti on jotenkin globaali tai helposti saatavilla osoitteessa
missä tahansa sovelluksessa. Voimme siis yrittää kapseloida tämän. Voimme tietysti siirtää sen hasRole toiminto:

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

Mutta se ei anna meille juuri mitään.

The Vartija Komponentti

Aika luoda komponentti, joka kapseloi koko logiikan. Nimesin sen Vartija ja haluan käyttää sitä näin.

 export const GuardedAppHeader: FC = () => { {
     return (
         
  • VainAdmin-komponentti
  • Vain käyttäjä-komponentti
  • >
  • Admin- ja käyttäjäkomponentti
  • Yleinen käyttöelementti
); }

Komponentti tarvitsee kaksi ominaisuutta. Ensimmäinen lapset vastuussa suojatusta sisällöstä. Toinen requiredRoles että
käsitellä rooleja, jotka antavat meille pääsyn.

Tarvitsemme tämän rakenteen edustuksen. Se on hyvin yksinkertainen. Laajennamme tyypin React.PropsWithChildren (rekvisiitta lasten kanssa) joka on lapset
omaisuus. Voit tietysti lisätä kyseisen ominaisuuden manuaalisesti tyyppiin ja jättää laajennuksen pois.

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

Myös itse komponentti on yksinkertainen. Käytämme uudelleen hasRole toiminto täällä.

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 ;
}
}
"`

Voisin sanoa, että lopeta tähän, mutta se olisi liian helppoa. Nyt meillä on komponentti, ja voimme käyttää sitä äärimmilleen 😀.

`GuardService`

Ensimmäinen vaihe on tarkastusten ulkoistaminen. currentUser on kovakoodattu arvo. Haluaisin kapseloida tämän arvon
johonkin palveluun, joka "osaa" tarkistaa roolit. Teknisesti se tarkoittaa, että siirretään hasRole funktio toiseen
luokka.

Luon yksinkertaisen käyttöliittymän IGuardService jolla on vain yksi ominaisuus - hasRole.

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

Yksinkertainen toteutus voisi näyttää tältä

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

Käyttääksemme sitä meidän on muutettava IGuardProperties ja käyttötapaus.

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

// ...

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

Vain ylläpitäjän komponentti
 

Vain käyttäjälle tarkoitettu komponentti

Ylläpitäjän ja käyttäjän komponentti
 
 

Yleinen käyttöelementti

 

);
}
```

Nyt komponentti näyttää seuraavalta:

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

Paljon parempi. GuardService erottaa meidät logiikasta, joka tarkistaa roolit. Voimme muuttaa sitä ilman seurauksia meidän
komponentti. Yleinen käyttötapaus on käyttää mockia testeissä ja jotain "oikeaa" toteutusta tuotantokoodissa.

Kielletty elementti

Seuraava parannus on mukautettujen Kielletty elementti. Nykyinen ratkaisu tekee tyhjän elementin. Ensin meidän on
muutos IGuardProps lisäämällä funktio, joka renderöidään kyseiselle elementille.

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

Tämä on valinnainen ominaisuus, jonka nimi päättyy kysymysmerkkiin. Se voi siis olla function tai undefined. Meidän on
käsitellä sitä Vartija komponentti.

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 (

Vain ylläpitäjän komponentti
 

Vain käyttäjälle tarkoitettu komponentti

Kielletty - vain moderaattori voi nähdä tämän.
}>
 

Moderaattori-komponentti

 

Ylläpitäjä- ja käyttäjäkomponentti
 
 

Yleinen käyttöelementti

 

);
}
```

Tyyppien joustavuus

Aika viimeiseen suureen muutokseen. Nykyisen version komponentti tukee vain rooleja merkkijono. Meillä voisi olla useita erilaisia
kiinteistötyypit, jotka haluaisimme tarkistaa. Numerot tai mukautetut tyypit eivät ole mitään erityistä. Lisään geneeristen ominaisuuksien tuen.

Ensimmäinen vaihe on muutokset IGuardService rajapinta. Toteutukset riippuvat testattavan arvon tyypistä. Se voi olla
olla mitä tahansa, joten käyttöliittymän pitäisi käsitellä sitä.

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

Nyt se ottaa array of ROOLI geneerinen tyyppi. Yksinkertainen toteutuksemme muuttuu hieman.

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

Meidän on lisättävä tyyppiparametri, mutta voisimme valmistella toteutuksen, joka tukee tyyppiä IRole rajapinta.

rajapinta IRole {
name: string;
}

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

Toinen vaihe on levittää tämä muutos IGuardProps.

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

Ja vastaavasti Vartija komponentti.

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

Ja käyttötapauksemme

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>Vain järjestelmänvalvojan komponentti</li>
                     </Guard>
                     <Guard<string&gt; requiredRoles={["USER"]} guardService={guardService}&gt;
                         <li>Vain käyttäjälle tarkoitettu komponentti</li>
                     </Guard>
                     <Guard<string&gt; requiredRoles={["MODERATOR"]} guardService={guardService}
                                    forbidden={() =&gt; <div>Kielletty - vain moderaattori voi nähdä tämän</div>}>
                         <li>Moderaattorikomponentti</li>
                     </Guard>
                     <Guard<string&gt; requiredRoles={["USER", "ADMIN"]} guardService={guardService}&gt;
                         <li>Ylläpitäjä- ja käyttäjäkomponentti</li>
                     </Guard>
                     <li>Yleinen käyttöelementti</li>
                 </ul>
             </nav>
         </header>
     );
 }

Tässä esimerkissä käytän molempia toteutuksia IGuardservice vain havainnollistamistarkoituksessa. Todellisissa käyttötapauksissa
luultavasti käyttää vain yhtä.

Erikoistuneet komponentit ja yhdistäminen

The Vartija voisi olla sisäkkäisiä. Muista vain, että pääsy ratkaistaan ulkoisimmasta instanssista käsin.

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>Vain järjestelmänvalvojan komponentti</li>
                         </Guard>
                         <Guard<string&gt; requiredRoles={["USER"]} guardService={guardService}&gt;
                             <li>Vain käyttäjälle tarkoitettu komponentti</li>
                         </Guard>
                         <li>Ylläpitäjä- ja käyttäjäkomponentti</li>
                         <Guard<string&gt; requiredRoles={["MODERATOR"]} guardService={guardService}
                                        forbidden={() =&gt; <div>Kielletty - vain moderaattori voi nähdä tämän</div>}>
                             <li>Moderaattorikomponentti</li>
                         </Guard>
                     </Guard>
                     <li>Yleinen käyttöelementti</li>
                 </ul>
             </nav>
         </header>
     );
 }

Yllä olevassa esimerkissä Moderaattorikomponentti ei voisi koskaan esiintyä, koska käyttäjä voi käsitellä vain yhtä roolia. Ensimmäinen Vartija rajoitukset
roolit ADMIN ja KÄYTTÄJÄ, joten MODERAATTORI ei koskaan läpäise ensimmäistä tarkastusta.

Voimme rakentaa erikoistuneita komponentteja, jotka piilottavat joitakin ominaisuuksia.

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

}

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

Vain ylläpitäjän komponentti
 


Vain käyttäjälle tarkoitettu komponentti


Forbidden - vain moderaattori voi nähdä tämän
}>

Moderaattori-komponentti



Ylläpitäjä- ja käyttäjäkomponentti

 

Yleinen käyttöelementti

);
}
```

Tässä tapauksessa AdminGuard määrittele ennalta ADMIN rooli. Seurauksena on, että meidän on nimenomaisesti määriteltävä tyyppi tyyppiä ROOLI tyyppi
parametri.

Yhteenveto

Tässä artikkelissa näytän, miten luodaan ja käytetään Vartija komponentti React:ssä. Aloitamme monimutkaisesta koodista, jota on vaikea
lukea ja ylläpitää. Kehitämme sen kehittäjäystävällisemmäksi ja otamme käyttöön mukautetun toiminnallisen komponentin. Seuraavaksi me
laajennetaan komponenttia lisäämällä lisätoimintoja, uudistetaan poimintapalvelua ja lisätään geneerisiä tyyppejä.

Lopuksi, meillä on komponentti, joka voidaan sisäkkäin on helppo testata ja ylläpitää.

Aiheeseen liittyvät artikkelit

Ohjelmistokehitys

React:n hyvät ja huonot puolet

Miksi kannattaa käyttää React:tä? Mitä etuja JavaScript-kirjastolla on? Saat vastaukset selville sukeltamalla tähän artikkeliin ja tutustumalla React:n käytön todellisiin etuihin.

Codest
Cezary Goralski Software Engineer

Tilaa tietopankkimme ja pysy ajan tasalla IT-alan asiantuntemuksesta.

    Tietoa meistä

    The Codest - Kansainvälinen ohjelmistokehitysyritys, jolla on teknologiakeskuksia Puolassa.

    Yhdistynyt kuningaskunta - pääkonttori

    • Toimisto 303B, 182-184 High Street North E6 2JA
      Lontoo, Englanti

    Puola - Paikalliset teknologiakeskukset

    • Fabryczna Office Park, Aleja
      Pokoju 18, 31-564 Krakova
    • Brain Embassy, Konstruktorska
      11, 02-673 Varsova, Puola

      Codest

    • Etusivu
    • Tietoa meistä
    • Palvelut
    • Tapaustutkimukset
    • Tiedä miten
    • Työurat
    • Sanakirja

      Palvelut

    • Se neuvoa-antava
    • Ohjelmistokehitys
    • Backend-kehitys
    • Frontend-kehitys
    • Staff Augmentation
    • Backend-kehittäjät
    • Pilvi-insinöörit
    • Tietoinsinöörit
    • Muut
    • QA insinöörit

      Resurssit

    • Faktoja ja myyttejä yhteistyöstä ulkoisen ohjelmistokehityskumppanin kanssa
    • Yhdysvalloista Eurooppaan: Miksi amerikkalaiset startup-yritykset päättävät muuttaa Eurooppaan?
    • Tech Offshore -kehityskeskusten vertailu: Tech Offshore Eurooppa (Puola), ASEAN (Filippiinit), Euraasia (Turkki).
    • Mitkä ovat teknologiajohtajien ja tietohallintojohtajien tärkeimmät haasteet?
    • Codest
    • Codest
    • Codest
    • Privacy policy
    • Verkkosivuston käyttöehdot

    Tekijänoikeus © 2025 by The Codest. Kaikki oikeudet pidätetään.

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