Prezentační a Komponent Kontejneru
Aktualizace od roku 2019: napsal jsem tento článek už dávno a moje názory se od té doby vyvinul. Zejména už nedoporučuji rozdělovat vaše komponenty takto. Pokud zjistíte, že je přirozené v codebase, tento vzor může být užitečné. Ale viděl jsem to vynucené bez nutnosti a s téměř dogmatickým zápalem až příliš mnohokrát. Hlavním důvodem, proč jsem to považoval za užitečné, bylo to, že mi umožnilo oddělit komplexní stavovou logiku od ostatních aspektů komponenty. Háčky mi dovolily udělat to samé bez libovolného rozdělení. Tento text je z historických důvodů ponechán nedotčený, ale neberte jej příliš vážně.
existuje jednoduchý vzor, který považuji za nesmírně užitečný při psaní aplikací React. Pokud jste už nějakou dobu reagovali, pravděpodobně jste to již objevili. Tento článek to vysvětluje dobře, ale chci přidat ještě několik bodů.
zjistíte, že vaše komponenty jsou mnohem jednodušší k opětovnému použití a důvodům, pokud je rozdělíte do dvou kategorií. Říkám jim kontejnerové a prezentační komponenty* ale také jsem slyšel tlusté a Hubené, chytré a hloupé, Stavové a čisté, obrazovky a komponenty atd. To vše není úplně stejné,ale základní myšlenka je podobná.
Moje prezentační komponenty:
- zajímá Vás, jak věci vypadají.
- může obsahovat jak prezentační, tak kontejnerové komponenty * * uvnitř, a obvykle mají některé vlastní značky DOM a styly.
- často umožňují uzavření prostřednictvím tohoto.rekvizita.dítě.
- nemají žádné závislosti na zbytku aplikace, jako jsou akce toku nebo obchody.
- neuvádějte, jak jsou data načtena nebo zmutována.
- přijímat data a zpětná volání výhradně prostřednictvím rekvizit.
- zřídka mají svůj vlastní stav (když ano, je to stav UI spíše než data).
- jsou zapsány jako funkční komponenty, pokud nepotřebují háčky stavu, životního cyklu nebo optimalizaci výkonu.
- Příklady: Stránka, Postranní Panel, Příběh, UserInfo, Seznam.
Moje komponenty kontejneru:
- se zabývají tím, jak věci fungují.
- Mohou obsahovat jak prezentační a kontejnerové komponenty** uvnitř, ale obvykle nemají žádnou DOM markup jejich vlastní s výjimkou některých balení divs, a nikdy žádné styly.
- Poskytněte data a chování prezentačním nebo jiným komponentám kontejneru.
- zavolejte akce toku a poskytněte je jako zpětná volání prezentačním komponentům.
- jsou často stavové, protože mají tendenci sloužit jako zdroje dat.
- se obvykle generují pomocí komponent vyššího řádu, jako je connect() z React Redux, createContainer() z Relay nebo Container.vytvořit () z Flux Utils, spíše než psaný ručně.
- Příklady: UserPage, FollowersSidebar, StoryContainer, FollowedUserList.
dal jsem je do různých složek, aby bylo toto rozlišení jasné.
výhody tohoto přístupu
- lepší oddělení obav. Lépe rozumíte své aplikaci a uživatelskému rozhraní tím, že píšete komponenty tímto způsobem.
- lepší použitelnost. Můžete použít stejnou prezentační komponentu se zcela odlišnými zdroji stavu a přeměnit je na samostatné komponenty kontejneru, které lze dále znovu použít.
- prezentační komponenty jsou v podstatě “paleta” vaší aplikace. Můžete je umístit na jednu stránku a nechat designéra vyladit všechny jejich variace, aniž byste se dotkli logiky aplikace. Na této stránce můžete spustit regresní testy obrazovky.
- to vás nutí extrahovat “komponenty rozvržení”, jako je postranní panel, stránka, ContextMenu a použít toto.rekvizita.děti místo duplikování stejné značky a rozvržení v několika komponentách kontejneru.
nezapomeňte, že komponenty nemusí emitovat DOM. Potřebují pouze stanovit hranice složení mezi obavami UI.
využijte toho.
kdy zavést kontejnery?
navrhuji, abyste nejprve začali vytvářet aplikaci pouze s prezentačními komponenty. Nakonec si uvědomíte, že procházíte příliš mnoho rekvizit po mezilehlých součástech. Když si všimnete, že některé komponenty nepoužívám rekvizity, které dostávají, ale pouze dopředu dolů a vy budete muset přepojit všechny ty intermediate komponenty, kdykoli děti potřebují více dat, je to dobrý čas představit některé komponenty kontejner. Tímto způsobem můžete získat data a podpěry chování ke složkám listů, aniž byste zatěžovali nesouvisející komponenty uprostřed stromu.
Jedná se o probíhající proces refaktorování, takže se nepokoušejte to napravit poprvé. Při experimentování s tímto vzorem si vytvoříte intuitivní smysl pro to, kdy je čas extrahovat některé kontejnery, stejně jako víte, kdy je čas extrahovat funkci. Moje bezplatná série Redux Egghead vám s tím může také pomoci!
Ostatní dichotomie
je důležité, abyste pochopili, že rozdíl mezi prezentačními komponenty a kontejnery není technický. Spíše je to rozdíl v jejich účelu.
naproti tomu zde je několik souvisejících (ale odlišných!) technické rozdíly:
- státní a bez státní příslušnosti. Některé komponenty použít Reagovat setState() metoda a některé ne. Zatímco kontejner složky mají tendenci být stavové a prezentační komponenty mají tendenci být bez státní příslušnosti, není to pevné pravidlo. Prezentační komponenty mohou být stavové a kontejnery mohou být také bez státní příslušnosti.
- třídy a funkce. Protože React 0.14, komponenty mohou být deklarovány jak jako třídy, tak jako funkce. Funkční komponenty jsou jednodušší definovat, ale postrádají některé funkce v současné době k dispozici pouze pro komponenty třídy. Některá z těchto omezení mohou v budoucnu zmizet, ale existují dnes. Protože funkční komponenty jsou srozumitelnější, doporučuji vám je používat, pokud nepotřebujete háčky stavu, životního cyklu nebo optimalizace výkonu, které jsou v tuto chvíli k dispozici pouze komponentám třídy.
- čistý a nečistý. Lidé říkají, že součást je čistá, pokud je zaručeno, že vrátí stejný výsledek vzhledem ke stejným rekvizitám a stavu. Čisté komponenty mohou být definovány jak jako třídy, tak jako funkce a mohou být stavové i bez státní příslušnosti. Dalším důležitým aspektem pure components je to, že se nespoléhají na hluboké mutace v rekvizitách nebo stavu, takže jejich vykreslovací výkon může být optimalizován mělkým porovnáním v háku shouldComponentUpdate (). V současné době mohou definovat pouze třídy shouldComponentUpdate (), ale to se může v budoucnu změnit.
prezentační komponenty i kontejnery mohou spadat do kterékoli z těchto kbelíků. Z mé zkušenosti, prezentační komponenty mají tendenci být bez státní funkce, a kontejnery mají tendenci být stavové čisté třídy. Nejedná se však o pravidlo, ale o pozorování, a viděl jsem přesně opačné případy, které dávaly smysl za konkrétních okolností.
neberte oddělení prezentačních a kontejnerových složek jako dogma. Někdy na tom nezáleží nebo je těžké nakreslit čáru. Pokud si nejste jisti, zda by konkrétní součást měla být prezentační nebo kontejner, může být příliš brzy na rozhodnutí. Netrap se tím!
příklad
tato podstata Michaela Chana to docela přibije.
Další Čtení
- začínáme s Redux
- Mixins jsou Mrtví, ať Žije Složení
- Komponent Kontejneru
- Atomic Web Design
- Budování Facebook News Feed s Relé
Poznámky pod čarou
* V dřívější verzi tohoto článku, který jsem nazval je “chytrý” a “hloupý” komponenty, ale tohle bylo příliš kruté prezentační komponenty a co je nejdůležitější, jsem opravdu vysvětlit rozdíl v jejich účelu. Užívám si nové podmínky mnohem lépe, a doufám, že vy taky!
* * v dřívější verzi tohoto článku jsem tvrdil, že prezentační komponenty by měly obsahovat pouze jiné prezentační komponenty. Už si nemyslím, že tomu tak je. Zda je komponenta prezentační komponentou nebo kontejnerem, je její implementační detail. Měli byste být schopni nahradit prezentační komponentu kontejnerem bez úpravy některého z míst volání. Proto, jak prezentační, tak kontejnerové komponenty mohou obsahovat další prezentační nebo kontejnerové komponenty v pohodě.