Apresentação e Recipiente de Componentes
Atualização a partir de 2019: eu escrevi este artigo há muito tempo e minha opinião desde então evoluiu. Em particular, não sugiro mais dividir os seus componentes assim. Se você achar natural em sua base de dados, este padrão pode ser útil. Mas vi-o ser aplicado sem necessidade e com fervor quase dogmático demasiadas vezes. A principal razão pela qual achei útil foi porque me deixou separar a complexa lógica de Estado de outros aspectos do componente. Hooks me deixa fazer a mesma coisa sem uma divisão arbitrária. Este texto é deixado intacto por razões históricas, mas não levá-lo muito a sério.
há um padrão simples que eu acho imensamente útil ao escrever aplicações React. Se você tem feito a reação por um tempo, você provavelmente já a descobriu. Este artigo explica-o bem, mas gostaria de acrescentar mais alguns pontos.
encontrará os seus componentes muito mais fáceis de reutilizar e raciocinar se os dividir em duas categorias. Eu chamo-lhes Container e componentes de apresentação* mas eu também ouvi gordura e Skinny, inteligente e burro, Stateful e puro, telas e Componentes, etc. Todos estes não são exatamente os mesmos, mas a idéia central é semelhante.
os meus componentes de apresentação:
- estão preocupados com o aspecto das coisas.
- pode conter tanto componentes de apresentação como de contêineres** no interior, e geralmente têm algumas marcas DOM e estilos próprios.
- muitas vezes permitem contenção através disso.adereco.filhos.
- não têm dependências do resto do Aplicativo, tais como ações de fluxo ou lojas.
- não especifique como os dados são carregados ou mutados.
- receber dados e callbacks exclusivamente através de adereços.
- raramente têm o seu próprio estado (quando têm, é o estado UI em vez de dados).
- são escritos como componentes funcionais, a menos que eles precisam de Estado, ganchos de ciclo de vida, ou otimizações de desempenho.
- Exemplos: Page, Sidebar, Story, UserInfo, List.
os meus componentes para contentores:
- estão preocupados com a forma como as coisas funcionam.
- pode conter tanto componentes de apresentação como de contêineres * * dentro, mas geralmente não tem nenhuma marca DOM própria, exceto para algumas divs de empacotamento, e nunca tem nenhum estilo.
- fornece os dados e o comportamento a componentes de contêineres.
- acções de fluxo de chamadas e fornecê-las como callbacks para os componentes de apresentação.
- são muitas vezes stateful, como eles tendem a servir como fontes de dados.
- são geralmente gerados usando componentes de ordem superior, tais como connect() a partir de Redux React, createContainer() a partir de relé, ou Container.criar () a partir de Utils de fluxo, em vez de escrito à mão.
- Examples: UserPage, FollowersSidebar, StoryContainer, FollowedUserList.
PU-los em pastas diferentes para tornar esta distinção clara.
benefícios desta abordagem
- melhor separação das preocupações. Você entende melhor seu aplicativo e sua IU escrevendo componentes desta forma.
- melhor reutilização. Você pode usar o mesmo componente de apresentação com fontes de estado completamente diferentes, e transformá-los em componentes de contêiner separados que podem ser reutilizados.
- os componentes de apresentação são essencialmente a “paleta”do seu aplicativo. Você pode colocá-los em uma única página e deixar o designer ajustar todas as suas variações sem tocar a lógica da aplicação. Você pode executar testes de regressão screenshot nessa página.
- isto obriga-o a extrair “componentes do layout”, como a barra lateral, página, ContextMenu e usar isto.adereco.crianças em vez de duplicar a mesma marcação e disposição em vários componentes do recipiente.Lembre-se, os componentes não têm de emitir DOM. Só precisam de estabelecer limites de composição entre as preocupações de IU.Tire proveito disso.Quando introduzir contentores?
sugiro que comece a construir o seu aplicativo com apenas componentes de apresentação em primeiro lugar. Eventualmente você vai perceber que você está passando muitos adereços para baixo os componentes intermediários. Quando você notar que alguns componentes não usam os adereços que eles recebem, mas apenas encaminhá-los para baixo e você tem que religar todos esses componentes intermediários a qualquer momento que as crianças precisam de mais dados, é uma boa hora para introduzir alguns componentes de contêiner. Desta forma você pode obter os dados e os adereços de comportamento para os Componentes da folha sem sobrecarregar os componentes não relacionados no meio da árvore.
este é um processo contínuo de refactoração por isso não tente acertar na primeira vez. À medida que você experimenta este padrão, você vai desenvolver um sentido intuitivo para quando é hora de extrair alguns contêineres, assim como você sabe quando é hora de extrair uma função. A minha série Grátis de Redux Egghead pode ajudar-te com isso também!
outras dicotomias
é importante que compreenda que a distinção entre os componentes de apresentação e os recipientes não é técnica. Pelo contrário, é uma distinção na sua finalidade.
em contraste, aqui estão alguns relacionados (mas diferentes!) distinções técnicas:
- Stateful e Stateless. Alguns componentes usam o método Reat setState() e outros não. enquanto os componentes de contêiner tendem a ser stateful e os componentes de apresentação tendem a ser apátridas, esta não é uma regra difícil. Componentes de apresentação podem ser stateful,e containers podem ser stateless demasiado.
- Classes e funções. Desde React 0.14, os componentes podem ser declarados como classes e como funções. Componentes funcionais são mais simples de definir, mas eles não possuem certas características atualmente disponíveis apenas para componentes de classe. Algumas dessas restrições podem desaparecer no futuro, mas existem hoje. Como os componentes funcionais são mais fáceis de entender, sugiro que você os use a menos que você precise de Estado, ganchos de ciclo de vida, ou otimizações de desempenho, que só estão disponíveis para os componentes de classe neste momento.
- puro e impuro. As pessoas dizem que um componente é puro se for garantido o retorno do mesmo resultado, dado os mesmos adereços e estado. Componentes puros podem ser definidos tanto como classes e funções, e podem ser stateful e stateless. Outro aspecto importante dos componentes puros é que eles não dependem de mutações profundas em adereços ou estado, de modo que o seu desempenho de renderização pode ser otimizado por uma comparação superficial em seu gancho shouldComponentUpdate (). Atualmente, apenas as classes podem definir o shouldComponentUpdate (), mas isso pode mudar no futuro.
ambos os componentes e recipientes de apresentação podem cair em qualquer um desses baldes. Na minha experiência, os componentes de apresentação tendem a ser funções puras sem estado, e os recipientes tendem a ser classes puras de Estado. No entanto, isto não é uma regra, mas uma observação, e eu vi os casos exatamente opostos que faziam sentido em circunstâncias específicas.
Não tome a separação dos componentes de apresentação e recipiente como um dogma. Às vezes não importa, ou é difícil traçar o limite. Se você se sentir inseguro sobre se um componente específico deve ser presentacional ou um recipiente, pode ser muito cedo para decidir. Não te preocupes!
Example
This gist by Michael Chan pretty much nails it.
Ler Mais
- primeiros passos com Redux
- Mixins são Mortos, viva a Composição
- Recipiente de Componentes
- o Atomic Web Design
- Edifício do Facebook Feed de Notícias com Relé
notas de Rodapé
* Em uma versão anterior do presente artigo, eu chamei-os de “inteligente” e “mudos” componentes mas este era demasiado severa para a apresentação de componentes e, o mais importante, realmente não explicar a diferença no seu propósito. Eu gosto dos novos termos muito melhor, e eu espero que você também!
* * numa versão anterior deste artigo I alegou que os componentes de apresentação deveriam conter apenas outros componentes de apresentação. Penso que já não é esse o caso. Se um componente é um componente de apresentação ou um recipiente é o seu detalhe de implementação. Você deve ser capaz de substituir um componente de apresentação com um recipiente sem modificar qualquer um dos sites de chamadas. Portanto, tanto os componentes de apresentação e container podem conter outros componentes de apresentação ou container muito bem.