Componenti per presentazioni e contenitori

Bismuto

Aggiornamento da 2019: ho scritto questo articolo molto tempo fa e le mie opinioni si sono evolute. In particolare, non suggerisco più di dividere i tuoi componenti in questo modo. Se lo trovi naturale nella tua base di codice, questo modello può essere utile. Ma l’ho visto applicato senza alcuna necessità e con fervore quasi dogmatico troppe volte. Il motivo principale per cui l’ho trovato utile era perché mi permetteva di separare la logica stateful complessa da altri aspetti del componente. Hooks mi lascia fare la stessa cosa senza una divisione arbitraria. Questo testo è rimasto intatto per ragioni storiche, ma non prenderlo troppo sul serio.

C’è un modello semplice che trovo immensamente utile quando si scrivono applicazioni React. Se hai fatto Reagire per un po’, probabilmente avete già scoperto. Questo articolo lo spiega bene, ma voglio aggiungere qualche altro punto.

Troverai i tuoi componenti molto più facili da riutilizzare e ragionare se li dividi in due categorie. Li chiamo Contenitore e componenti di presentazione * ma ho anche sentito Grassi e magri, intelligenti e stupidi, Stateful e Puri, schermi e componenti, ecc. Questi non sono tutti esattamente gli stessi, ma l’idea di base è simile.

I miei componenti di presentazione:

  • Si preoccupano di come appaiono le cose.
  • Può contenere sia componenti di presentazione che di contenitore** all’interno e di solito hanno alcuni markup DOM e stili propri.
  • Spesso consentono il contenimento tramite questo.puntelli.bambino.
  • Non hanno dipendenze dal resto dell’app, come azioni Flux o negozi.
  • Non specificare come i dati vengono caricati o modificati.
  • Ricevere dati e callback esclusivamente tramite oggetti di scena.
  • Raramente hanno il proprio stato (quando lo fanno, è lo stato dell’interfaccia utente piuttosto che i dati).
  • Sono scritti come componenti funzionali a meno che non necessitino di stato, hook del ciclo di vita o ottimizzazioni delle prestazioni.
  • Esempi: Pagina, Barra laterale, Storia, UserInfo, Elenco.

Componenti del mio contenitore:

  • Si occupano di come funzionano le cose.
  • Può contenere sia componenti di presentazione che di contenitore * * all’interno, ma di solito non hanno alcun markup DOM a parte alcuni div di wrapping e non hanno mai stili.
  • Fornire i dati e il comportamento ai componenti del contenitore di presentazione o di altro tipo.
  • Chiama le azioni Flux e forniscile come callback ai componenti di presentazione.
  • Sono spesso stateful, in quanto tendono a servire come origini dati.
  • Vengono generalmente generati utilizzando componenti di ordine superiore come connect() da React Redux, createContainer () da Relay o Container.create () da Flux Utils, piuttosto che scritto a mano.
  • Esempi: UserPage, FollowersSidebar, StoryContainer, FollowedUserList.

Li ho messi in diverse cartelle per rendere chiara questa distinzione.

Vantaggi di questo approccio

  • Migliore separazione delle preoccupazioni. Comprendi meglio la tua app e la tua interfaccia utente scrivendo i componenti in questo modo.
  • Migliore riusabilità. È possibile utilizzare lo stesso componente di presentazione con origini di stato completamente diverse e trasformarle in componenti contenitore separati che possono essere ulteriormente riutilizzati.
  • I componenti di presentazione sono essenzialmente la “tavolozza”della tua app. Puoi metterli su una singola pagina e lasciare che il progettista modifichi tutte le loro varianti senza toccare la logica dell’app. È possibile eseguire test di regressione screenshot in quella pagina.
  • Questo ti costringe ad estrarre “componenti di layout” come Sidebar, Page, ContextMenu e usarlo.puntelli.figli invece di duplicare lo stesso markup e layout in diversi componenti del contenitore.

Ricorda, i componenti non devono emettere DOM. Devono solo fornire limiti di composizione tra i problemi dell’interfaccia utente.

Approfittane.

Quando introdurre i contenitori?

Ti suggerisco di iniziare a costruire la tua app con solo componenti di presentazione prima. Alla fine ti renderai conto che stai passando troppi oggetti di scena lungo i componenti intermedi. Quando noti che alcuni componenti non usano gli oggetti di scena che ricevono ma semplicemente li inoltrano verso il basso e devi ricablare tutti quei componenti intermedi ogni volta che i bambini hanno bisogno di più dati, è un buon momento per introdurre alcuni componenti del contenitore. In questo modo è possibile ottenere i dati e gli oggetti di comportamento sui componenti foglia senza gravare sui componenti non correlati nel mezzo dell’albero.

Questo è un processo in corso di refactoring, quindi non cercare di farlo bene la prima volta. Come si sperimenta con questo modello, si svilupperà un senso intuitivo per quando è il momento di estrarre alcuni contenitori, proprio come si sa quando è il momento di estrarre una funzione. La mia serie Reduxheadhead gratuita potrebbe aiutarti anche con questo!

Altre Dicotomie

È importante capire che la distinzione tra i componenti di presentazione e i contenitori non è tecnica. Piuttosto, è una distinzione nel loro scopo.

Al contrario, ecco alcuni correlati (ma diversi!) distinzioni tecniche:

  • Stateful e apolide. Alcuni componenti usano il metodo React setState () e altri no. Mentre i componenti del contenitore tendono ad essere stateful e i componenti di presentazione tendono ad essere stateless, questa non è una regola difficile. I componenti di presentazione possono essere stateful e anche i contenitori possono essere stateless.
  • Classi e funzioni. Poiché React 0.14, i componenti possono essere dichiarati sia come classi che come funzioni. I componenti funzionali sono più semplici da definire ma mancano di alcune funzionalità attualmente disponibili solo per i componenti della classe. Alcune di queste restrizioni potrebbero andare via in futuro, ma esistono oggi. Poiché i componenti funzionali sono più facili da capire, ti suggerisco di usarli a meno che tu non abbia bisogno di stato, ganci del ciclo di vita o ottimizzazioni delle prestazioni, che sono disponibili solo per i componenti della classe in questo momento.
  • Puro e impuro. La gente dice che un componente è puro se è garantito per restituire lo stesso risultato dato gli stessi oggetti di scena e stato. I componenti puri possono essere definiti sia come classi che come funzioni e possono essere sia stateful che stateless. Un altro aspetto importante dei componenti puri è che non si basano su mutazioni profonde in props o state, quindi le loro prestazioni di rendering possono essere ottimizzate da un confronto superficiale nel loro hook shouldComponentUpdate (). Attualmente solo le classi possono definire shouldComponentUpdate () ma ciò potrebbe cambiare in futuro.

Sia i componenti di presentazione che i contenitori possono cadere in uno di questi bucket. Nella mia esperienza, i componenti di presentazione tendono ad essere funzioni pure stateless e i contenitori tendono ad essere classi pure stateful. Tuttavia questa non è una regola ma un’osservazione, e ho visto i casi esattamente opposti che avevano senso in circostanze specifiche.

Non prendere la separazione dei componenti di presentazione e contenitore come un dogma. A volte non importa o è difficile tracciare la linea. Se non ti senti sicuro se un componente specifico debba essere presentato o un contenitore, potrebbe essere troppo presto per decidere. Non preoccuparti!

Esempio

Questo succo di Michael Chan lo inchioda praticamente.

bibliografia

  • iniziamo con Redux
  • Mixins sono Morto, Lunga vita a Composizione
  • Componenti Contenitore
  • Atomic Web Design
  • Costruzione di Facebook News Feed con Relè

Note a piè di pagina

* In una versione precedente di questo articolo li ho chiamati “smart” e “muto”, componenti, ma questo era troppo difficili per la presentazione dei componenti e, soprattutto, non ha davvero spiegare la differenza nel loro scopo. Mi piacciono i nuovi termini molto meglio, e spero che lo fai anche tu!

* * In una versione precedente di questo articolo ho affermato che i componenti di presentazione dovrebbero contenere solo altri componenti di presentazione. Non credo più che questo sia il caso. Se un componente è un componente di presentazione o un contenitore è il suo dettaglio di implementazione. Dovresti essere in grado di sostituire un componente di presentazione con un contenitore senza modificare nessuno dei siti di chiamata. Pertanto, sia i componenti di presentazione che quelli del contenitore possono contenere altri componenti di presentazione o contenitore.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.