Massiivi teisendamine elementide loendiks React abil on üsna lihtne, põhimõtteliselt on vaja vaid seda massiivi kaardistada ja tagastada iga massiivi elemendi jaoks sobiv element.
On ka veel üks asi, mida peate meeles pidama ja see on React Võti atribuuti, peab see olema igal renderdatud loendi elemendil. See kontseptsioon on üks esimesi asju, mida iga front-end arendaja õpib. React nende reisi alguses. Nüüd kaevume veidi sügavamale, et uurida, miks see nii on ja millal me saame võtta mõningaid otseteid.
Miks on meil seda võtmeatribuuti vaja?
Kõige lihtsam vastus oleks siinkohal "optimeerida re-renderdusi", kuid täielikum vastus peab vähemalt mainima mõistet React Kooskõlastamine. See on protsess, mille käigus selgitatakse välja, kuidas uuendada kasutajaliidest kõige tõhusamal viisil. Et seda kiiresti teha, React peab otsustama, milliseid elementide puu osi on vaja uuendada ja milliseid mitte. Asi on selles, et DOMis võib olla palju elemente ja iga elemendi võrdlemine otsustamisel, millist neist tuleks uuendada, on üsna kallis. Selle optimeerimiseks, React rakendab difing-algoritmi, mis põhineb kahel eeldusel:
- Kaks erinevat tüüpi elementi ei ole kunagi ühesugused - seega renderige need uuesti.
- Arendajad saavad käsitsi aidata seda protsessi optimeerida võtmeatribuutide abil, nii et elemendid, isegi kui nende järjekord on muutunud, on võimalik kiiremini lokaliseerida ja võrrelda.
Selle põhjal võime järeldada, et iga React võti peaks samuti olema unikaalne (elementide loetelus, mitte globaalselt) ja stabiilne (ei tohiks muutuda). Aga mis võib juhtuda, kui nad ei ole tat?
Ainulaadsus, stabiilsus ja massiiviindeks
Nagu me juba varem mainisime, React klahvid peaks olema stabiilne ja ainulaadne. Kõige lihtsam viis selle saavutamiseks on kasutada unikaalset ID-d (näiteks andmebaasist) ja anda see igale elemendile massiivi kaardistamisel üle, lihtne. Aga kuidas on olukordadega, kus meil ei ole ID-d, nime või muid unikaalseid identifikaatoreid, mida igale elemendile edastada? Noh, kui me ei edasta midagi võtmeks, React võtab vaikimisi praeguse massiivi indeksi (kuna see on selles nimekirjas unikaalne), et seda meie eest käsitleda, kuid annab meile ka kena veateate konsooli:

Miks see nii on? Vastus on selles, et massiivi indeks ei ole stabiilne. Kui elementide järjekord muutub, muutub iga võti ja meil on probleem. Kui React kohtub olukorras, kus elementide järjekord loetelus on muutunud, püüab ta neid ikkagi võrrelda võtmete järgi, mis tähendab, et iga võrdlus lõpeb komponendi ümberehitamisega ja selle tulemusena ehitatakse kogu loetelu uuesti nullist üles. Lisaks sellele võib tekkida ootamatuid probleeme, näiteks komponentide oleku uuendamine elementide puhul nagu kontrollimata sisendid ja muud maagilised raskesti vea kõrvaldatavad probleemid.
Erandid
Tuleme tagasi massiivi indeksi juurde. Kui kasutame seda kui React võti võib olla nii problemaatiline, miks React kasutab seda vaikimisi? Kas on mõni kasutusjuhtum, kus see on okei? Vastus on jah, kasutusjuhtumiks on staatilised nimekirjad. Kui sa oled kindel, et renderdatav nimekiri ei muuda kunagi oma järjekorda, siis on ohutu kasutada massiivi indeksit, kuid pea meeles, et kui sul on mingid unikaalsed identifikaatorid, siis on ikkagi parem neid kasutada selle asemel. Samuti võite märgata, et indeksite edastamine võtmetena muudab React veateade kaob, samal ajal käivitades mõned välised linterid, et kuvada viga või hoiatus. Selle põhjuseks on asjaolu, et indeksite selgesõnalist kasutamist võtmetena peetakse halvaks tavaks ja mõned linterid võivad seda käsitleda veana, samas kui React ise peab seda "arendajad teavad, mida nad teevad" olukorraks - seega ärge tehke seda, kui te tõesti ei tea, mida teete. Mõned näited, millal võib olla okei kasutada seda erandit, oleks rippmenüü staatilise nuppude loeteluga või elementide loetelu kuvamine teie ettevõtte aadressiandmetega.
Alternatiiv andmekogumipõhisele võtmele
Oletame, et ükski eespool nimetatud variantidest ei ole meie jaoks võimalik. Näiteks peame kuvama stringide massiivil põhinevat elementide nimekirja, mida saab dubleerida, kuid mida saab ka ümber järjestada. Sellisel juhul ei saa me kasutada ühtegi stringi, sest need ei ole unikaalsed (see võib põhjustada ka mõningaid maagilisi vigu) ja massiivi indeks ei ole piisavalt hea, sest me muudame elementide järjekorda. Viimane asi, millele me saame sellises olukorras toetuda, on mõne välise identifikaatori kasutamine. Pidage meeles, et see peab olema stabiilne, nii et me ei saa lihtsalt kasutada Math.random(). On olemas mõned NPM-i paketid, mida me saame sellistel juhtudel kasutada, näiteks "uuid" pakett. Sellised tööriistad aitavad meil hoida meie nimekirjade võtmed stabiilsena ja ainulaadsetena isegi siis, kui me ei leia oma andmekogust õigeid identifikaatoreid. Me peaksime kaaluma andmebaasi ID ja massiiviindeksi kasutamist (kui võimalik) kõigepealt, et minimeerida meie pakettide arvu, mida kasutatakse projekt.
Kokkuvõtteks
- Iga element nimekirjas React elementidel peaks olema unikaalne ja stabiilne võtmeatribuut,
- React klahvid kasutatakse selleks, et kiirendada Lepitusprotsess ja vältida nimekirjade elementide asjatut ümberehitamist,
- Parim allikas võtmete jaoks on andmete sisestamise unikaalne ID (näiteks andmebaasist),
- Võid kasutada massiivi indeksit võtmena, kuid ainult staatilise loendi puhul, mille järjekord ei muutu,
- Kui ei ole muud võimalust saada stabiilseid ja unikaalseid võtmeid, kaaluge mõne välise ID-teenuse pakkuja, näiteks paketi "uuid" kasutamist.
Loe edasi:
Miks peaksite (tõenäoliselt) kasutama Typescript'i
Kuidas mitte tappa projekti halbade kodeerimistavadega?
NextJS-i andmete hankimise strateegiad