præsentations-og Beholderkomponenter
opdatering fra 2019: jeg skrev denne artikel for længe siden, og mine synspunkter har siden udviklet sig. Især foreslår jeg ikke at opdele dine komponenter som dette længere. Hvis du finder det naturligt i din kodebase, kan dette mønster være praktisk. Men jeg har set det håndhævet uden nogen nødvendighed og med næsten dogmatisk inderlighed alt for mange gange. Hovedårsagen til, at jeg fandt det nyttigt, var fordi det lod mig adskille kompleks stateful logik fra andre aspekter af komponenten. Hooks lad mig gøre det samme uden en vilkårlig opdeling. Denne tekst efterlades intakt af historiske grunde, men tag den ikke for alvorligt.
der er et simpelt mønster, jeg finder uhyre nyttigt, når jeg skriver React-applikationer. Hvis du har reageret i et stykke tid, har du sandsynligvis allerede opdaget det. Denne artikel forklarer det godt, men jeg vil tilføje et par flere punkter.
du finder dine komponenter meget lettere at genbruge og ræsonnere om, hvis du deler dem i to kategorier. Jeg kalder dem Container-og Præsentationskomponenter*, men jeg hørte også fedt og mager, Smart og Dum, Stateful og ren, skærme og komponenter osv. Disse er alle ikke helt ens, men kerneideen er ens.
mine præsentationskomponenter:
- er bekymret for, hvordan tingene ser ud.
- kan indeholde både præsentations-og containerkomponenter** indeni og har normalt nogle egne DOM-markeringer og stilarter.
- tillader ofte indeslutning via dette.rekvisit.barn.
- har ingen afhængigheder af resten af appen, f.eks.
- angiv ikke, hvordan dataene indlæses eller muteres.
- Modtag data og tilbagekald udelukkende via rekvisitter.
- har sjældent deres egen tilstand (når de gør det, er det UI-tilstand snarere end data).
- er skrevet som funktionelle komponenter, medmindre de har brug for tilstands -, livscykluskroge eller ydelsesoptimeringer.
- Eksempler: Side, Sidebjælke, Historie, UserInfo, Liste.
mine containerkomponenter:
- er optaget af, hvordan tingene fungerer.
- kan indeholde både præsentations-og containerkomponenter** indeni, men har normalt ikke nogen egen DOM-markering bortset fra nogle indpakningsdivs og har aldrig nogen stilarter.
- Giv data og adfærd til præsentations-eller andre containerkomponenter.
- ring til Flukshandlinger, og angiv disse som tilbagekald til præsentationskomponenterne.
- er ofte stateful, da de har tendens til at tjene som datakilder.
- genereres normalt ved hjælp af komponenter med højere ordre, f.eks.Opret () fra strøm Utils, snarere end skrevet i hånden.
- Eksempler: UserPage, Følgersidebar, StoryContainer, Følgeduserlist.
jeg sætter dem i forskellige mapper for at gøre denne skelnen klar.
fordele ved denne tilgang
- bedre adskillelse af bekymringer. Du forstår din app og din brugergrænseflade bedre ved at skrive komponenter på denne måde.
- bedre genanvendelighed. Du kan bruge den samme præsentationskomponent med helt forskellige tilstandskilder og omdanne dem til separate beholderkomponenter, der kan genbruges yderligere.
- Præsentationskomponenter er i det væsentlige din apps “palette”. Du kan placere dem på en enkelt side og lade designeren finjustere alle deres variationer uden at røre ved appens logik. Du kan køre screenshot regressionstest på den side.
- dette tvinger dig til at udtrække “layoutkomponenter” såsom sidebjælke, side, kontekstmenu og bruge dette.rekvisit.børn i stedet for at duplikere den samme markering og layout i flere containerkomponenter.
husk, komponenter behøver ikke at udsende DOM. De behøver kun at give kompositionsgrænser mellem UI-bekymringer.
Udnyt det.
Hvornår skal man indføre containere?
jeg foreslår, at du først begynder at opbygge din app med bare præsentationskomponenter. Til sidst vil du indse, at du passerer for mange rekvisitter ned mellemkomponenterne. Når du bemærker, at nogle komponenter ikke bruger rekvisitterne, de modtager, men blot videresender dem, og du er nødt til at tilslutte alle disse mellemliggende komponenter, når børnene har brug for flere data, er det et godt tidspunkt at introducere nogle containerkomponenter. På denne måde kan du få dataene og adfærdsrekvisitterne til bladkomponenterne uden at belaste de ikke-relaterede komponenter midt i træet.
dette er en løbende proces med refactoring, så prøv ikke at få det rigtigt første gang. Når du eksperimenterer med dette mønster, vil du udvikle en intuitiv fornemmelse for, hvornår det er tid til at udtrække nogle containere, ligesom du ved, hvornår det er tid til at udtrække en funktion. Min gratis Egghead-serie kan også hjælpe dig med det!
andre dikotomier
det er vigtigt, at du forstår, at sondringen mellem præsentationskomponenterne og containerne ikke er teknisk. Det er snarere en sondring i deres formål.
derimod er her et par relaterede (men forskellige!) tekniske forskelle:
- statsløs og statsløs. Nogle komponenter bruger React setState () – metoden, og nogle gør det ikke. mens containerkomponenter har tendens til at være statlige, og præsentationskomponenter har tendens til at være statsløse, er dette ikke en hård regel. Præsentationskomponenter kan være statlige, og containere kan også være statsløse.
- klasser og funktioner. Siden React 0.14 kan komponenter erklæres både som klasser og som funktioner. Funktionelle komponenter er enklere at definere, men de mangler visse funktioner, der i øjeblikket kun er tilgængelige for klassekomponenter. Nogle af disse begrænsninger kan forsvinde i fremtiden, men de findes i dag. Fordi funktionelle komponenter er lettere at forstå, foreslår jeg, at du bruger dem, medmindre du har brug for tilstand, livscykluskroge eller ydelsesoptimeringer, som kun er tilgængelige for klassekomponenterne på dette tidspunkt.
- ren og uren. Folk siger, at en komponent er ren, hvis den garanteres at returnere det samme resultat givet de samme rekvisitter og tilstand. Rene komponenter kan defineres både som klasser og funktioner og kan være både statlige og statsløse. Et andet vigtigt aspekt af rene komponenter er, at de ikke er afhængige af dybe mutationer i rekvisitter eller tilstand, så deres gengivelsesydelse kan optimeres ved en lav sammenligning i deres shouldcomponentupdate() krog. I øjeblikket kan kun klasser definere shouldComponentUpdate (), men det kan ændre sig i fremtiden.
både præsentationskomponenter og containere kan falde i en af disse spande. Efter min erfaring har præsentationskomponenter tendens til at være statsløse rene funktioner, og containere har tendens til at være statlige rene klasser. Dette er dog ikke en regel, men en observation, og jeg har set de nøjagtige modsatte tilfælde, der gav mening under særlige omstændigheder.
tag ikke præsentations-og beholderkomponentseparationen som et dogme. Nogle gange betyder det ikke noget, eller det er svært at tegne linjen. Hvis du føler dig usikker på, om en bestemt komponent skal være præsentativ eller en beholder, kan det være for tidligt at beslutte. Sved det ikke!
eksempel
denne kerne af Michael Chan negler det stort set.
yderligere læsning
- Kom godt i gang med Reduks
- blandingerne er døde, længe leve sammensætning
- Containerkomponenter
- Atomic design
- opbygning af Facebook nyhedsfeed med relæ
fodnoter
* i en tidligere version af denne artikel kaldte jeg dem” smarte “og” dumme ” komponenter, men dette var alt for hårdt for præsentationskomponenterne og vigtigst af alt forklarede ikke rigtig forskellen i deres formål. Jeg nyder de nye vilkår meget bedre, og jeg håber, at du også gør det!
** i en tidligere version af denne artikel hævdede jeg, at præsentationskomponenter kun skulle indeholde andre præsentationskomponenter. Jeg tror ikke længere, at dette er tilfældet. Om en komponent er en præsentationskomponent eller en container er dens implementeringsdetaljer. Du skal være i stand til at erstatte en præsentationskomponent med en container uden at ændre nogen af opkaldssiderne. Derfor kan både præsentations-og containerkomponenter indeholde andre præsentations-eller containerkomponenter helt fint.