Como Usar Componentes Compostos e Evitar o Apropcalipse
1. O que são componentes compostos?
Segundo Kent.C Dodds componentes compostos são componentes que trabalham juntos para concluir uma tarefa específica. Geralmente um componente pai e filhos trabalhando juntos. O Objetivo é entregar uma API mais flexível e expressiva.
Vamos lá
Imagine que o seu trabalho é fazer componentes então sua próxima tarefa é criar um componente de Tabs. Até aí tudo bem você cria seu componente <Tabs/> e entrega ele feliz da vida.
Imagine o componente assim
O componente Aceita uma propriedade Items com o buttonName que será o nome do botão em tela e o componente que será renderizado quando aquele botão foi clicado gerando a seguinte UI
Você entrega o componente, as pessoas começam a usar e todo mundo fica feliz. Mas alguém chega e fala.
Então eu queria que as Tabs ficassem em baixo e o conteúdo em cima
Ae você cria uma props nova openAbove , faz alguns ifs no componente e entrega novamente. E todo mundo fica feliz
Então chega alguém e fala
Eu queria estilizar o botão do componente pra uma outra cor.
Você cria duas novas props e chama de buttonClassName e buttonActiveClassName.
Acho que você entendeu onde quero chegar…
ISSO PODE ACONTECER MUITAS VEZES
Pode ter tantas props no seu componente que pode Gerar o APROPCALIPSE!
Então como evitar essa catástrofe?
Composição de componentes não é a solução para o fim do mundo mas pode ser uma alternativa bem interessante quando se trata de flexibilidade e expressividade.
Resolvendo o problema com componentes compostos
A solução é criar uma API em que o usuário tenha mais responsabilidade sobre a utilização. É como você em vez de entregar o componente pronto entregar todas as peças e ferramentas para o usuário fazer do jeito que ele quiser. Isso é chamado de Inversão de controle.
Observe como usar nosso novo componente abaixo.
Temos um componente pai e os filhos. Temos um
<Tabs.tab>
Um componente de tab que caso o desenvolvedor deseje um componente já pré estilizado pode usar com facilidade.
<Tabs.CustomTab>
Podemos criar nossos próprio botões a partir desse botão. Recebe um children que é uma função com a propriedade id.
<Tabs.TabPanel/>
Exibe uma informação caso o id seja o mesmo de uma <Tabs.CustomTab> ou <Tabs.Tab/>.
Tabs.useTabs()
que nos retorna duas propriedades:
activeId
Nos permite fazer a verificação ao estilizar nossos CustomTabs
selectTab
Nos permite fazer a navegação dentro dos nossos TabPanels e talvez até dentro dos CustomTabs.
Esses componentes compartilham estado internamente!
Estes componentes implicitamente compartilham estado internamente, o usuário final do componente não precisa saber os estados que o componente compartilha internamente. Apenas montar sua UI a partir dele.