React plussid ja miinused
Miks tasub kasutada React? Millised on selle JavaScript raamatukogu eelised? Vastuste leidmiseks sukelduge sellesse artiklisse ja avastage React kasutamise tegelikud eelised.

Õppige, kuidas lihtsustada ja parandada komponentide nähtavust Reacts, kasutades tingimuslikku renderdamist ja valvekomponente.
Täna tahaksin arutada, kuidas kontrollida komponentide nähtavus React-s. Aga enne kui me alustame on väike
lahtiütlemine:
Esitatud lahendus ei ole väga turvaline, mis tähendab, et teie rakendus on kaitstud "häkkerite" (kes iganes need ka ei ole) eest.
Pidage meeles, et peate kaitsma oma lõpp-punkte ja kasutama häid tavasid rakenduse disainimisel. See lahendus ainult
teeb teie töö veidi lihtsamaks.
Üks kõige levinumaid funktsioone on näidata komponenti ainult mõnele kasutajale, kellel on teatud õigused,
rollid või privileegid. Üldine lahendus on lisada mõned kui
s kuni kood, kontrollige käsitsi tingimusi ja näidake või mitte elemente.
Vaatame, et SimpleAppHeader
komponent, mis sisaldab vähe navigatsioonielemente.
<!-- wp:paragraph -->
<p><code>typescript jsx<br>
eksport const SimpleAppHeader: FC = () => {<br>
return (<br>
<header><br>
<nav><br>
<ul><br>
{<br>
currentUser.role === "ADMIN" &&<br>
<li>AinultAdmin komponent</li><br>
}<br>
{<br>
currentUser.role === "USER" &&<br>
<li>Kasutajale ainult komponent</li><br>
}<br>
{<br>
(currentUser.role === "ADMIN" || currentUser.role === "USER") &&<br>
<li>Komponent ainult administraator ja kasutaja</li><br>
}<br>
<li>Üldine kasutuselement</li><br>
</ul><br>
</nav><br>
</header><br>
)<br>
}<br>
</code></p>
<!-- /wp:paragraph -->
Paistab "mitte halb". Tõenäoliselt saaksite keerukuse vähendamiseks kontrolle kapseldada funktsioonidesse. currentUser
on mingi objekt
mis on roll
omadus, kuid see võib olla mis tahes, mida me soovime kasutada meie kontrollimehhanismi subjektina.
Sellel koodil on mõned probleemid. Kui projekt kasvab me ilmselt kasutame seda konstruktsiooni paljudes kohtades. Nii et me peame kopeerima,
kuidagi, tingimused. Seda koodi on raske säilitada ja muuta tulevikus. Eriti siis, kui juurdepääsureeglid muutuvad
aeg, nt peame muutma currentUser
millekski muuks. Seda on väga raske testida. Sa pead kirjutama palju teste
lihtsalt selleks, et kontrollida, kas teie seisund on korras.
Aeg on seda koodi veidi lihtsustada. Me võiksime välja võtta mõned meetodid ja muuta koodi lühemaks ja vähem keerulisemaks:
const isAdmin = (roll: string): boolean => roll === "ADMIN";
const isUser = (role: string): boolean => roll === "USER";
const isAdminOrUser = (roll: string): boolean => isAdmin(roll) || isUser(roll);
eksport const SimplifiedAppHeader: FC = () => { {
return (
{
isAdmin(currentUser.role) &&
Ainult administraatori komponent
}
{
isUser(currentUser.role) &&
Ainult kasutaja komponent
}
{
(isAdminOrUser(currentUser.role)) &&
Ainult administraatori ja kasutaja komponent
}
Üldine kasutuselement
)
}
```
Paistab paljulubav. Me vähendame müra od korduvad read. Kood on loetavam ja lihtsamini hooldatav. Kuid vaadake
funktsioon isAdminOrUser
. Meil on ainult kaks rolli. Kui me võtame kasutusele kolmanda rolli, peame looma veel ühe funktsioonide kogumi.
mis ühendab rollid. Aeg on teine versioon.
Kehtestage funktsioon hasRole
mis on asenduseks meie isX
funktsioonid.
const hasRole = (roll: string, requiredRole: string[]): boolean => {
let found: string | undefined = requiredRole.find(s => roll === s);
return found !== undefined;
}
export const FilteringAppHeader: FC = () => { {
return (
{
hasRole(currentUser.role, ["ADMIN"]) &&
Ainult administraatori komponent
}
{
hasRole(currentUser.role, ["USER"]) &&
Ainult kasutaja komponent
}
{
hasRole(currentUser.role, ["ADMIN", "USER"]) &&
Ainult Admin ja User komponent
}
Üldine kasutuselement
)
}
```
Nüüd näeb hea välja. Meil on endiselt tingimused html-koodi osas, kuid nüüd saame testida hasRole
funktsioon ja usaldus, et see
kasutatakse õigete parameetritega. Rollide lisamine või muutmine on nüüd lihtsam. Kasutame massiivi, mis sisaldab kõiki
rollid, mida me vajame.
See lahendus on siiski seotud currentUser
objekt. Eeldus on, et objekt on kuidagi globaalne või kergesti ligipääsetav in
mis tahes kohas rakenduses. Seega võime proovida seda kapseldada. Loomulikult saame selle liigutada hasRole
funktsioon:
const hasRole = (requiredRole: string[]): boolean => { {
let found: string | undefined = requiredRole.find(s => currentUser.role === s);
return found !== undefined;
}
Kuid see ei anna meile peaaegu midagi.
Valvur
KomponentAeg luua komponent, mis kapseldab kogu loogikat. Ma nimetasin selle Valvur
ja nii ma tahan seda kasutada.
export const GuardedAppHeader: FC = () => { {
return (
);
}
Komponent vajab kahte omadust. Esimene lapsed
vastutab kaitstud sisu eest. Teine requiredRoles
et
käsitseda rollide massiivi, mis annab meile juurdepääsu.
Me vajame selle struktuuri esindatust. See on väga lihtne. Me laiendame tüübi React.PropsWithChildren (rekvisiidid lastega)
mis on lapsed
vara. Loomulikult võite lisada selle omaduse käsitsi oma tüübile ja jätta laienduse välja.
liides IGuardProps extends React.PropsWithChildren {
requiredRoles: string[];
}
Komponent ise on samuti lihtne. Me kasutame uuesti hasRole
funktsioon siin.
eksport 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 ;
}
}
"`
Ja ma võiksin öelda, et lõpetage siin, aga see oleks liiga lihtne. Nüüd on meil komponent, ja me võime seda äärmuseni kasutada 😀.
Esimene samm on kontrollide väljapoole viimine. currentUser
on kõvakooditud väärtus. Tahaksin seda väärtust kapseldada
mõnda teenusesse, mis "teab", kuidas rolle kontrollida. Tehniliselt tähendab see, et me liigume hasRole
funktsioon teisele
klass.
Loen lihtsa liidese IGuardService
millel on ainult üks omadus - hasRole
.
eksport liides IGuardService {
checkRole: (roles: string[]) => boolean;
}
Nüüd võiks lihtne rakendamine välja näha nii
klass SimpleGuard rakendab IGuardService {
checkRole(roles: string[]): boolean {
let found: string | undefined = roles.find(e => e === currentUser.role);
return found !== undefined;
}
}
Selle kasutamiseks peame muutma IGuardProperties
ja kasutusjuhend.
export interface IGuardProps extends React.PropsWithChildren {
requiredRoles: string[];
guardService: IGuardService;
}
// ...
const AppHeader: FC = () => {
const guardService = new SimpleGuard();
return (
Ainult administraatorite komponent
Ainult kasutaja komponent
Administraatori ja kasutaja komponent
Üldine kasutuselement
);
}
```
Nüüd näeb komponent välja:
eksport const Guard = (props: IGuardProps) => { {
if (props.guardService.checkRole(props.requiredRoles)) {
return (
{props.children}
);
} else {
return ;
}
}
Palju parem. GuardService
eraldavad meid loogikast, mis kontrollib rolle. Me võime seda muuta ilma tagajärgedeta meie
komponent. Tavaline kasutusjuhtum on kasutada mocki testides ja mõningaid "reaalseid" rakendusi tootmiskoodis.
Järgmine parandus on kohandatud käitlemise Keelatud
element. Praegune lahendus muudab elemendi tühjaks. Kõigepealt peame
muuta IGuardProps
lisades funktsiooni, mis muudab selle elemendi.
export interface IGuardProps extends React.PropsWithChildren {
requiredRoles: string[];
guardService: IGuardService;
forbidden?: () => React.ReactNode;
}
See on vabatahtlik omadus, nimi lõpeb küsimärgiga. Nii et see võib olla funktsioon või undefined
. Me peame
käsitseda seda Valvur
komponent.
eksport const Guard = (props: IGuardProps) => {
if (props.guardService.checkRole(props.requiredRoles)) {
return (
{props.children}
);
} else if (props.forbidden === undefined) {
return ;
} else {
return (
{props.forbidden()}
);
}
}
// ...
eksport const AppHeader: FC = () => { {
const guardService = new SimpleGuard();
return (
Ainult administraatorite komponent
Ainult kasutaja komponent
Keelatud - seda saab näha ainult moderaator
}>
Moderaatori komponent
Administraatori ja kasutaja komponent
Üldine kasutuselement
);
}
```
Aeg viimaseks suureks muutuseks. Praegune versioon komponent toetab ainult rolle nagu string
. Meil võiks olla mitu erinevat
kinnisvaratüübid, mida me tahaksime kontrollida. Numbrid või kohandatud tüübid ei ole midagi erilist. Ma lisan geneeriliste omaduste toe.
Esimene samm on muutused IGuardService
liides. Rakendused sõltuvad testitava väärtuse tüübist. See võib olla
olla midagi, nii et kasutajaliides peaks sellega hakkama saama.
export interface IGuardService {
checkRole: (roles: ROLE[]) => boolean;
}
Nüüd võtab see massiivi ROLL
üldine tüüp. Meie lihtne rakendamine muutub veidi.
class SimpleGuard implements IGuardService {
checkRole(roles: string[]): boolean {
let found: string | undefined = roles.find(e => e === currentUser.role);
return found !== undefined;
}
}
Me peame lisama tüübiparameetri, kuid me võiksime valmistada implementatsiooni, mis toetab IRole
liides.
liides IRole {
name: string;
}
//...
class RoleGuardService implements IGuardService {
checkRole(roles: IRole[]): boolean {
let found: IRole | undefined = roles.find(e => e === userWithRole.role);
return found !== undefined;
}
}
```
Teine samm on selle muudatuse levitamine IGuardProps
.
interface IGuardProps extends React.PropsWithChildren {
requiredRoles: ROLE[];
guardService: IGuardService;
forbidden?: () => React.ReactNode;
}
Ja vastavalt Valvur
komponent.
eksport const Guard = (props: IGuardProps) => { {
if (props.guardService.checkRole(props.requiredRoles)) {
return (
{props.children}
);
} else if (props.forbidden === undefined) {
return ;
} else {
return (
{props.forbidden()}
);
}
}
Ja meie kasutusjuhtumid
eksport const AppHeader: FC = () => { {
const guardService = new SimpleGuard();
const roleService = new RoleGuardService();
return (
<header>
<nav>
<ul>
<Guard<IRole> requiredRoles={[{nimi: "ADMIN"}]} guardService={roleService}>
<li>Ainult administraatori komponent</li>
</Guard>
<Guard<string> requiredRoles={["USER"]} guardService={guardService}>
<li>Ainult kasutaja komponent</li>
</Guard>
<Guard<string> requiredRoles={["MODERATOR"]} guardService={guardService}
forbidden={() => <div>Keelatud - ainult moderaator saab seda näha</div>}>
<li>Moderaatori komponent</li>
</Guard>
<Guard<string> requiredRoles={["USER", "ADMIN"]} guardService={guardService}>
<li>Administraatori ja kasutaja komponent</li>
</Guard>
<li>Üldine kasutuselement</li>
</ul>
</nav>
</header>
);
}
Selles näites kasutan ma mõlemat rakendust IGuardservice
lihtsalt illustreerimiseks. Reaalsetes kasutusjuhtumites saate
tõenäoliselt kasutada ainult ühte.
The Valvur
võib olla pesitsetud. Pea meeles, et juurdepääs lahendatakse järjekorras kõige välise instantsi.
eksport const NestAppHeader: FC = () => { {
const guardService = new SimpleGuard();
return (
<header>
<nav>
<ul>
<Guard<string> requiredRoles={["USER", "ADMIN"]} guardService={guardService}>
<Guard<string> requiredRoles={["ADMIN"]} guardService={guardService}>
<li>Ainult administraatori komponent</li>
</Guard>
<Guard<string> requiredRoles={["USER"]} guardService={guardService}>
<li>Ainult kasutaja komponent</li>
</Guard>
<li>Administraatori ja kasutaja komponent</li>
<Guard<string> requiredRoles={["MODERATOR"]} guardService={guardService}
forbidden={() => <div>Keelatud - ainult moderaator saab seda näha</div>}>
<li>Moderaatori komponent</li>
</Guard>
</Guard>
<li>Üldine kasutuselement</li>
</ul>
</nav>
</header>
);
}
Ülaltoodud näites Moderaatori komponent
ei saa kunagi ilmuda, sest kasutaja saab käsitleda ainult ühte rolli. Esimene Valvur
piirangud
rollid ADMIN
ja KASUTAJA
, nii et MODERAATOR
ei lähe kunagi esimesest kontrollist läbi.
Me saame luua spetsialiseeritud komponendid, mis varjavad mõned omadused.
eksport const AdminGuard = (props: Omit) => { {
return
{props.children}
}
//...
eksport const SpecializedAppHeader: FC = () => { {
const guardService = new SimpleGuard();
return (
Ainult administraatorite komponent
Ainult kasutaja komponent
Forbidden - ainult moderaator saab seda näha
}>
Moderaatori komponent
Administraatori ja kasutaja komponent
Üldine kasutuselement
);
}
```
Sel juhul AdminGuard
eelnevalt kindlaks määrata ADMIN
roll. Tagajärjed, me peame selgesõnaliselt määratleda tüüpi ROLL
tüüp
parameeter.
Selles artiklis näitan teile, kuidas luua ja kasutada Valvur
komponent React. Me alustame keerulisest koodist, mida on raske
lugeda ja hooldada. Me arendame selle arendajasõbralikumaks ja võtame kasutusele kohandatud funktsionaalse komponendi. Järgmisena me
laiendada komponenti lisafunktsionaalsuse lisamisega, refaktoorida ekstraheerimise teenust ja lõpuks lisada geneerilisi tüüpe.
Lõpuks, meil on komponent, mida saab nested on lihtne testida ja säilitada.