presentatie-en containeronderdelen

Bismut

Update van 2019: ik schreef dit artikel een lange tijd geleden en mijn standpunten zijn sindsdien geëvolueerd. In het bijzonder, Ik stel niet meer voor om je componenten op deze manier te splitsen. Als je het natuurlijk vindt in je codebase, kan dit patroon handig zijn. Maar ik heb het zonder enige noodzaak en met bijna dogmatische ijver veel te vaak zien afdwingen. De belangrijkste reden dat ik vond het nuttig was omdat het liet me complexe stateful logica scheiden van andere aspecten van de component. Hooks laat me hetzelfde doen zonder een willekeurige verdeling. Deze tekst is om historische redenen intact gelaten, maar neem het niet te serieus.

er is een eenvoudig patroon dat ik enorm nuttig vind bij het schrijven van React applications. Als je al een tijdje React doet, heb je het waarschijnlijk al ontdekt. Dit artikel legt het goed uit, maar Ik wil nog een paar punten toevoegen.

u zult uw componenten veel gemakkelijker hergebruiken en redeneren als u ze in twee categorieën opdeelt. Ik noem ze Container en Presentationele componenten* maar ik hoorde ook vet en mager, slim en Dom, Stateful en puur, schermen en componenten, enz. Deze zijn allemaal niet precies hetzelfde, maar de kernidee is vergelijkbaar.

mijn presentatiecomponenten:

  • zijn bezorgd over hoe de dingen eruit zien.
  • kan zowel presentatiecomponenten als containercomponenten * * bevatten, en hebben meestal een eigen dom-opmaak en-stijlen.
  • staan vaak insluiting via dit toe.prop.kinder.
  • zijn niet afhankelijk van de rest van de app, zoals Flux acties of stores.
  • specificeer niet hoe de gegevens worden geladen of gemuteerd.
  • ontvang uitsluitend gegevens en callbacks via props.
  • hebben zelden hun eigen status (als ze dat doen, is het UI-status in plaats van gegevens).
  • worden geschreven als functionele componenten, tenzij ze status, levenscyclushaken of prestatieoptimalisaties nodig hebben.
  • Voorbeelden: Page, Sidebar, Story, UserInfo, List.

mijn containercomponenten:

  • houden zich bezig met hoe dingen werken.
  • kan zowel presentatiecomponenten als containercomponenten * * bevatten, maar hebben meestal geen eigen DOM-opmaak, behalve sommige wrappingdiv’ s, en hebben nooit stijlen.
  • Geef de gegevens en het gedrag van presentatiecomponenten of andere containercomponenten.
  • Call Flux acties en geef deze als callbacks aan de presentatiecomponenten.
  • zijn vaak stateful, omdat ze meestal als gegevensbronnen dienen.
  • worden meestal gegenereerd met behulp van hogere orde componenten zoals connect () van React Redux, createContainer() van Relay, of Container.create() uit Flux Utils, in plaats van met de hand geschreven.
  • Voorbeelden: UserPage, FollowersSidebar, StoryContainer, FollowedUserList.

ik zet ze in verschillende mappen om dit onderscheid duidelijk te maken.

voordelen van deze aanpak

  • betere scheiding van belangen. U begrijpt uw app en uw gebruikersinterface beter door componenten op deze manier te schrijven.
  • betere herbruikbaarheid. U kunt dezelfde presentatiecomponent gebruiken met volledig verschillende statusbronnen en deze omzetten in afzonderlijke containercomponenten die verder kunnen worden hergebruikt.
  • Presentatiecomponenten zijn in wezen het “palet”van uw app. U kunt ze op een enkele pagina en laat de ontwerper tweak al hun variaties zonder het aanraken van de logica van de app. U kunt screenshot regressietests uitvoeren op die pagina.
  • dit dwingt u om “opmaakcomponenten” zoals zijbalk, pagina, ContextMenu te extraheren en dit te gebruiken.prop.kinderen in plaats van het dupliceren van dezelfde opmaak en lay-out in verschillende container componenten.

onthoud dat componenten geen DOM hoeven uit te zenden. Ze hoeven alleen de compositiegrenzen tussen UI-concerns te bieden.

profiteer daarvan.

Wanneer moeten Containers worden ingevoerd?

ik stel voor dat u eerst begint met het bouwen van uw app met alleen presentatiecomponenten. Uiteindelijk zul je beseffen dat je het passeren van te veel rekwisieten langs de tussenliggende componenten. Wanneer u merkt dat sommige componenten geen gebruik maken van de rekwisieten die ze ontvangen, maar alleen doorsturen naar beneden en je moet al die tussencomponenten opnieuw bedraden wanneer de kinderen meer gegevens nodig hebben, is het een goed moment om een aantal container componenten te introduceren. Op deze manier kunt u de gegevens en het gedrag rekwisieten aan de bladcomponenten te krijgen zonder de ongerelateerde componenten in het midden van de boom te belasten.

dit is een doorlopend proces van refactoring, dus probeer het niet de eerste keer goed te doen. Als je experimenteert met dit patroon, ontwikkel je een intuïtief gevoel voor wanneer het tijd is om een aantal containers te extraheren, net zoals je weet wanneer het tijd is om een functie te extraheren. Mijn gratis Redux Egghead serie kan u helpen met dat ook!

andere dichotomieën

het is belangrijk dat u begrijpt dat het onderscheid tussen de presentatiecomponenten en de containers geen technische is. Integendeel, het is een onderscheid in hun doel.

daarentegen zijn hier een paar verwante (maar anders!) technische onderscheidingen:

  • Stateful en stateloos. Sommige componenten gebruiken React setState() methode en sommige niet. terwijl container componenten hebben de neiging om stateful en presentationele componenten hebben de neiging om stateloos te zijn, dit is niet een harde regel. Presentationele componenten kunnen stateful zijn, en containers kunnen ook stateloos zijn.
  • klassen en functies. Sinds React 0.14 kunnen componenten zowel als klassen als als functies worden gedeclareerd. Functionele componenten zijn eenvoudiger te definiëren, maar ze missen bepaalde functies die momenteel alleen beschikbaar zijn voor klasse componenten. Sommige van deze beperkingen kunnen in de toekomst verdwijnen, maar ze bestaan vandaag de dag. Omdat functionele componenten gemakkelijker te begrijpen zijn, stel ik voor dat u ze gebruikt, tenzij u state, lifecycle hooks of prestatieoptimalisaties nodig hebt, die op dit moment alleen beschikbaar zijn voor de klassencomponenten.
  • zuiver en onzuiver. Mensen zeggen dat een component puur is als het gegarandeerd hetzelfde resultaat oplevert met dezelfde rekwisieten en staat. Zuivere componenten kunnen zowel als klassen en functies worden gedefinieerd, en kunnen zowel stateful als statenloos zijn. Een ander belangrijk aspect van pure componenten is dat ze niet vertrouwen op diepe mutaties in rekwisieten of toestand, zodat hun rendering prestaties kunnen worden geoptimaliseerd door een ondiepe vergelijking in hun shouldComponentUpdate() haak. Momenteel kunnen alleen klassen definiëren shouldComponentUpdate (), maar dat kan veranderen in de toekomst.

zowel presentatiecomponenten als containers kunnen in een van deze bakken vallen. In mijn ervaring zijn presentatiecomponenten meestal stateloze pure functies, en containers hebben de neiging om stateful pure klassen te zijn. Maar dit is geen regel, maar een observatie, en ik heb precies het tegenovergestelde gevallen gezien die zinvol waren in specifieke omstandigheden.

neem de scheiding tussen presentatie en container niet als een dogma. Soms maakt het niet uit of is het moeilijk om de grens te trekken. Als u zich onzeker voelt over de vraag of een specifieke component presentationeel of een container moet zijn, is het misschien te vroeg om te beslissen. Maak je niet druk!

voorbeeld

deze kern van Michael Chan is vrijwel perfect.

Verder Lezen

  • Aan de Slag met Redux
  • Mixins zijn Dood, Lang leve de Samenstelling
  • Container Componenten
  • Atomic Web Design
  • het Bouwen van de Facebook nieuwsfeed met Relais

Voetnoten

* In een eerdere versie van dit artikel dat ik noemde hen “smart” en “domme” componenten, maar deze was te hard om de voorgestelde componenten en, belangrijker nog, niet echt verklaren het verschil in hun doel. Ik geniet veel beter van de nieuwe Voorwaarden, en ik hoop dat u dat ook doet!

** in een eerdere versie van dit artikel stelde ik dat presentatiecomponenten alleen andere presentatiecomponenten mogen bevatten. Ik denk niet langer dat dit het geval is. Of een component een presentationele component of een container is de implementatie detail. U moet in staat zijn om een presentationele component te vervangen door een container zonder wijziging van een van de call sites. Daarom kunnen zowel presentatiecomponenten als containercomponenten prima andere presentatiecomponenten of containercomponenten bevatten.

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd.