Kuidas vältida kompositsiooniga puurimist

Foto autor Rawpixel saidil Unsplash

React.js on üks populaarsemaid kasutajaliideste raamistikke. See on suurepärane komponentpõhine raamistik koos deklaratiivse API-ga, mis võimaldab arendajal mõelda kasutajaliidesele kui oleku ja rekvisiitide funktsioonile, mitte aga aja funktsioonile. Teisisõnu, peate kirjeldama oma komponendi välimust sisestatud andmete põhjal.

Esmane andmete edastamise viis on rekvisiitide kaupa. Lihtsamalt öeldes on rekvisiidid argumentideks funktsioonidele, mis tagastavad JSX-i. Tegelikult on komponendi kõige lihtsam vorm just see: JavaScripti funktsioon.

const Header = rekvisiidid => {
    tagasi (
         
            

{props.title}

         
    ); }

Rekvisiite saab sama komponendi jaoks kasutada mitme asja jaoks. Ülaltoodud näites kasutame seda css-klassi seadistamiseks: tume või hele. Seda kasutatakse ka päisesildi andmete edastamiseks. Seejärel saame seda komponenti kasutada, edastades rekvisiidid atribuutidena meie JSX-is, näiteks järgmiselt:

const App = rekvisiidid => {
    tagasi (
         
                      
    ); }

Nagu näete, võivad rekvisiidid olla väga võimsad. Kui neid rakendatakse valel viisil, võib nendega toime tulla väga keeruline. Üks suurimaid rekvisiitidega „ei-ei” on teha seda, mida nimetatakse „tugipuurimiseks”. Prop-puurimine on see, kui tugivarustus antakse komponendile ainult selleks, et see lapsele edasi anda.

const Vanem = ({klassinimi, pealkiri}) => {
    tagasi (
         
            {...}                       
    ); }

Ülaltoodud näites antakse pealkirja rekvisiit vanemale, kuid vanem kasutab seda ainult selleks, et anda see alamkomponendile. See ei ole ideaalne viis andmete edastamiseks. Ütleme nii, et meie lastekomponendil on veel üks tugiteenus, mida peame ära kasutama, nüüd peame selle tugikomponendi edastama ainult vanemkomponendile, et see siis lapsele edasi anda. Mida rohkem aega möödub ja meie koodide baas kasvab, seda enam veaohtlikud on meie andmed ja komponendid. (BTW, ülaltoodud näites kasutan ära ES6 operaatorit, mida nimetatakse hävitamiseks, mille kohta saate rohkem teada MDN-ist)

Hoolimata asjaolust, et teame seda vältida, hiilib rekvisiidi puurimine vaikselt sisse, isegi meid märkamata. Siin on reaalse elu näide projektist, mille kallal ma töötasin. Töötasin kangelase jaotises, millel oli pealkiri, alapealkiri ja loend nuppudest tegevusele. Sellega alustasin (lihtsustasin näite jaoks, et seda oleks hõlpsam lugeda):

const Hero = ({pealkiri, alapealkiri, ctas}) => {
    tagasi (
         
             {title} 
             {subtiiter} 
            
               {ctas.map (cta => )}
            
         
    );
}

Ülaltoodud näites oli kolm rekvisiiti: pealkiri, subtiitrid ja cta-massiiv (üleskutse tegevustele). Pealkiri ja subtiitrid pannakse vastavatesse komponentidesse ja siis kaardistame ctas-i, et saada massiivi LinkButtons. Seda on üsna lihtne järgida ja see töötas suurepäraselt.

Hiljem sattusin vajadusele, et mu rakenduses oleks kuskil mujal LinkButtons. Õnneks on Reaxi abil koodi taaskasutamine hõlbus ja ma tegelesin nuppude rea uuesti oma kangelaskomponendiga, et saaksin seda mõlemas kohas uuesti kasutada. Sellega ma lõpetasin:

const ActionButtons = ({tegevused}) => {
    tagasi (
       
          {action.map (action => )}
       
    );
}
const Hero = ({pealkiri, alapealkiri, ctas}) => {
    tagasi (
         
             {title} 
             {subtiiter} 
            
         
    );
}

Kas sa nägid, mis juhtus? Ma ei märganud seda alguses. See oli nii lihtne, et vajaminevat osa oli võimalik ümber refinantseerida, et ma isegi ei märganud, et olin just enda jaoks puurimisolukorra loonud. Lasin kangelaskomponendis ctas-propsi ainult selleks, et ümber pöörata ja teisele komponendile edasi anda. See võis hiljem mulle mõnevõrra suuri peavalusid tekitada ja proovisin ainult koodi korduvkasutamist.

Õnneks püüdsin end kinni ja kujundasin koodi uuesti nii:

const Hero = ({pealkiri, alapealkiri, lapsed}) => {
    tagasi (
         
             {title} 
             {subtiiter} 
            {lapsed}
         
    );
}

   

Nagu näete, ei renderda ma enam oma kangelase komponenti ActionButtons enam selgesõnaliselt. Pakun lastele lihtsalt tugiteenuseid, mis on kättesaadavad igale Reaxi komponendile. See muster paneb juhtimisseadme tagasi arendajate kätte, et valida, mida ja millal seal midagi rentida. Seejärel kannan komponendi ActionButtons lapsena kangelasele Hero. See võimaldab mul edastada andmed otse komponendile ActionButtons, ilma et kangelaskomponent peaks isegi teadma midagi ActionButtonsi komponendi API kohta.

Komponentide läbimise mustrit lastel nimetatakse kompositsiooniks. See on võimas muster, mis võimaldab nii komponentide lahutamist kui ka koodi taaskasutamist. Kui soovite lisateavet kompositsiooni ja selle kasutamise kohta, soovitaksin teil tutvuda Reacti alustamise lehega Kompositsioon vs pärand.

Minu koodi eeliseks on nüüd see, et kuna ActionButtonsi komponent paraneb ja muutub, ei pea kangelaskomponent seda teadma. See andis kangelaskomponendile ka suurema paindlikkuse, kuna seda ei ühendatud enam ActionButtonsi komponendiga, nii et nüüd saab see muuta seda, mida mul kunagi vaja võib olla, või üldse mitte midagi. Minu koodi baasi kasvades on mu kood palju hooldatavam.