Este artigo foi inspirado post: https://medium.com/teamsubchannel/react-component-patterns-e7fb75be7bb
Este post também está disponível no Medium: Padrõ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?
- render
- state
- props
- context
- 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
[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.
[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({})().
[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.
[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!
Cara, parabéns pelo compartilhamento de conhecimento. Objetivo, claro e simples.
Muito obrigado!