Este artigo foi inspirado post: https://medium.com/teamsubchannel/react-component-patterns-e7fb75be7bb

Este post também está disponível no MediumPadrões para construir componentes em React no meu perfil no Medium

Os componentes são o coração do React, então entendê-los é um dos caminhos para criar estruturas da aplicação da forma mais eficiente.

O exemplo dado neste artigo foi inspirado em uma excelente apresentação que Michael Chan deu no React component patterns. Recomendo assistir o vídeo.

O que é um componente

De acordo com o reactjs.org, “componentes permitem que você quebre a interface em pedaços independentes e reutilizáveis, e permitem vários níveis de isolamento destes componentes”.

A primeira vez que você executa um comando como:

npm install react

Você ganha uma coisa: um componente e suas API’s. Similar a funções JavaScript, um componente aceita entradas chamadas “props” e retorna elementos React, que descrevem (declara) como a interface deverá ser no final. Por este motivo o React é referenciado como uma API declarativa, por que diz o que você quer na interface e o React toma conta do restante.

Pense no fato de ser declarativo como você pegar um taxi para o destino, você diz ao motorista onde ir e ele / ela faz o caminho para chegar lá. Imperativo seria o oposto – você dirige sozinho para o destino.

API dos componentes React

Que API’s vem de presente quando você instala o React? Aqui listo 5 e eles são:

O que vem no framework do React?

  1. render
  2. state
  3. props
  4. context
  5. lifecycle events

Embora um componente seja totalmente capaz de utilizar o que a API acima oferece, você vai perceber que alguns componentes irão usar alguns destes enquanto outros componentes usarão outras partes da API exclusivamente. E há uma linha divisória entre duas categorias que são referenciadas como stateful e stateless. Stateful tipicamente utiliza API’s de estado: render, state e lifecycle events. Stateless são componentes como render, props e context.

É aqui que introduzimos o conceito de padrões de componentes (component patterns). Os padrões de componente usam as melhores práticas e onde primeiramente foi introduzido o conceito de dividir os dados em uma camada lógica e uma camada de apresentação. Dividindo essas responsabilidades pelos componentes, você pode criar um código mais reutilizável, assim como componentes coesos que são usados para construir interfaces complexas. Isto é especialmente importante quando construímos sistemas e experiência do usuário (UX) em larga escala.


Padrões de componente (componentes patterns)

Os padrões de componentes mais comuns são:

  • Container
  • Presentational
  • Higher order components (HOC’s)
  • Render callback

Container

Um container faz a requisição para obter os dados e renderiza seus sub-componentes, e é isto” – Jason Bonta

 

O azul no diagrama acima representa o container component e em cinza o presentational component.
Com os lifecycle events, você pode conectar os estados do componente usando o Redux ou Flux (tem também o Saga), e como isso passar dados nos componentes filho na forma de propriedades. O container renderiza a composição da interface dos componentes de apresentação e componentes filho. Para ter acesso a toda parte da API sem estado, um container deve ser um componente classe ao invés de um componente apenas funcional. No exemplo abaixo, nós temos um componente do tipo classe chamado Greeting, que tem estado, um ciclo de vida com os métodos componentDidMount() e render.
 

[gist id=”a02d2ed674fd97573580c549ef390e25″]

Neste exemplo, o componente é uma stateful class. Para fazer o componente Greeting um componente do tipo container, a gente divide os componentes de apresentação, como ilustrado abaixo.

Componentes de apresentação (Presentational)

Os componentes de apresentação utiliza o props, render, e context (API’s sem estado) e pode ser funcionais, sem estado, chamadas de funções puras.

[gist id=”491acb7fd297f7496666205ea4535ed0″]

Componentes de apresentação recebem dados e callbacks somente do parâmetro props, que pode provê dados para o container ou o componente pai.

 

O azul representa o componente de apresentação no React e o cinza o container. Juntos, container e componentes de apresentação encapsula a lógica para os componentes envolvidos.

[gist id=”bb117114d081e062782af7da0c713a5c”]

Como você pôde ver, eu removi a parte de apresentação da classe Greeting para um componente funcional sem estado. Claro, este é um exemplo simples – para apps mais complexas, isto é fundamental.

Higher order components (HOC’s)

Os Higher order components (componentes de ordem superior) são funções que tem  um componente como argumento e retorna um novo componente.

Este é um padrão poderoso para requisitar dados de quaisquer número de componentes e pode ser usado para reutilizar lógica do componente. Pense no react-router-v4 e Redux. Com o react-router-v4, você pode usar withRouter() para herdar métodos passados como props para seus componentes. E com o Redux, você pode acessar propriedades adicionais com o connect({})().

 

Os HOC em React, que são representados pela linha, que é uma função que retorna um novo componente

[gist id=”c9baafb39f9c2227c85798e6d00de803″]

Quando exportamos nosso componente, estou envolvendo ele em um componente do react-router-v4 com withRouter(). No ciclo dos eventos como o componentDidMount(), estou atualizando o estado com o valor fornecido por this.props.location.pathname. Quando envolvemos o componente com withRouter(), a classe agora pode acessar suas propriedades via props, como this.props.location.pathname. Este é apenas um exemplo de vários!

Renderizando callbacks

Similar ao componentes superiores (HOC), a renderização no padrão de callbacks são usados para compartilhar e reusar a mesma lógica do componente. Enquanto vários desenvolvedores tendem a aprender mais a utilizarem o HOC para reutilizarem a lógica, há muitas razões ainda para tirarmos vantagem dos callbacks no render, e isto é bem explicado pelo Michael Jackson em “Never write another HOC.” Só para ilustrar alguns pontos chaves, renderizar callbacks dá a luxúria de reduzir a colisão de namespace e ilustra melhor de onde exatamente a lógica deve vir.

 

A linha tracejada azul reprender o render callbak no React

[gist id=”f0a3c4f95e9cd03b3185095193e07ed4″]

Acima da classe Counter, estamos aninhando o this.props.children no método render e dando o this.state como argumento. Abaixo da classe App, sou capaz de inserir meu componente no componente Counter, e acessar a lógica do Counter também. O callback no render é a parte na linha 28, onde tenho { state => () } – bam! Agora tenho acesso ao estado do componente Counter!

Obrigado pela leitura!

Estamos abertos a sugestões para melhorar as explicações – acabamos que aprendemos ao escrever e estamos longe de ser perfeito e isto é apenas uma introdução ao conceito de React component patterns.

Quer aprender React na prática?

Com o Gitpay você pode trabalhar contribuindo com um projeto open source construído com o React. Veja nossas issues, cadastre-se na plataforma e veja as tarefas disponíveis para começar a criar soluções com o React , aprender e ser recompensado!

Fontes:

3 Replies to “Padrões para construir componentes com React”

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *