Componentização React: Como Dividir Componentes sem Criar Caos
O que é componentização em React
Componentização em React é o processo de dividir a interface em unidades menores e independentes, cada uma responsável por uma única parte da tela ou do comportamento. Um componente bem componentizado faz uma coisa, tem um nome que descreve exatamente essa coisa, e pode ser lido sem abrir mais três arquivos para entender o que ele faz.
Na prática, quase todo projeto React começa organizado e vai perdendo essa organização
aos poucos. Cada feature nova entra como mais um if dentro do componente que já existe,
porque é mais rápido do que parar para pensar onde ela deveria morar. Seis meses depois,
existe um arquivo de 400 linhas que ninguém quer abrir, e toda mudança nele carrega o
risco de quebrar outra parte que ninguém lembra que estava ali.
Quando faz sentido quebrar um componente
Um componente pede divisão quando um destes três sinais aparece, e quanto mais sinais juntos, mais urgente é a refatoração.
O primeiro é prop drilling: uma prop que atravessa dois ou três componentes que não usam ela, só para chegar no componente de baixo que precisa. Isso indica que o componente do meio não devia existir como está, ou que a informação devia vir de outro lugar, como um gerenciador de estado em vez de uma cadeia de props.
O segundo é o tamanho do JSX. Se o retorno de um componente não cabe na tela sem rolar, provavelmente existem duas ou três seções visuais distintas ali dentro, cada uma candidata a virar seu próprio componente.
O terceiro é o nome. Dashboard, PaginaProduto, TelaCheckout descrevem uma página
inteira, não uma função específica. Um bom nome de componente responde "o que isso faz"
em poucas palavras: CardProduto, ResumoDoPedido, BotaoDeCompra. Quando o nome só
existe porque o componente representa "aquela parte da tela", ele provavelmente devia se
dividir em partes que tenham nome próprio.
Padrões de composição e quando usar cada um
Existem três formas comuns de compor componentes em React, e cada uma resolve um problema diferente. Escolher a errada por hábito é tão custoso quanto não dividir nada.
Container e apresentação separa a lógica, como busca de dados e estado, de um componente que só recebe props e desenha a tela. Funciona bem quando o mesmo layout precisa aparecer com fontes de dados diferentes, como uma lista de produtos que vem da API em produção e de um mock nos testes.
Compound components usa o próprio JSX como API, no estilo <Select><Select.Option /></Select>. Compensa quando o componente pai precisa compartilhar estado interno com
os filhos sem expor esse estado como prop, como um menu que sabe qual item está aberto.
O custo é a curva de aprendizado: quem nunca viu o padrão demora para entender como os
filhos conversam com o pai.
Children como função, também chamado de render props, passa uma função como filho para o componente decidir o que renderizar com base num dado que só o pai conhece, como a posição do mouse ou o estado de um formulário. Hoje a maior parte desse caso é resolvida com hooks customizados, que entregam o mesmo comportamento sem aninhar JSX. Vale reservar render props para quando o consumidor realmente precisa controlar o como renderizar, não só o o quê.
Como refatorar um componente monolítico em partes menores
Quebrar um componente de 400 linhas de uma vez, num único commit, é a forma mais fácil de introduzir um bug que só aparece em produção. O caminho mais seguro é incremental.
- Leia o componente inteiro e marque, num comentário temporário, onde cada responsabilidade começa e termina: busca de dados, validação, renderização de cada seção visual.
- Extraia primeiro a parte mais isolada, aquela que não depende de estado do resto do componente. Geralmente é uma seção visual pura, como um cabeçalho ou um card.
- Escreva um teste rápido para o componente extraído antes de seguir, mesmo que simples. Ele garante que a extração não mudou o comportamento visível.
- Repita a extração uma responsabilidade por vez, sempre validando no navegador entre um passo e outro. Não acumule duas extrações no mesmo commit.
- Só depois de extrair tudo que é visual, olhe o estado que sobrou no componente pai. Se ele ainda gerencia estado que pertence a um filho específico, mova esse estado para dentro do filho.
- Remova os comentários temporários do passo 1 e confirme que o nome de cada componente novo descreve uma função clara, não a posição dele na tela antiga.
Esse processo também vale como critério para decidir entre refatorar aos poucos ou reescrever do zero: se a extração passo a passo continua revelando estrutura aproveitável, refatorar resolve. Se cada passo esbarra em acoplamento que só existe porque a arquitetura de base está errada, a reescrita de uma parte específica pode custar menos do que insistir na extração.
Erros comuns de componentização
O erro mais citado é o componente gigante, mas o oposto também tem custo real e aparece com menos frequência nas discussões sobre o tema.
Dividir demais cria componentes de dez linhas com nomes como Wrapper, Container ou
InnerBox, que não representam nenhuma função e só existem porque alguém seguiu a regra
"componentes pequenos são sempre melhores" sem parar para perguntar se aquele pedaço faz
sentido sozinho. O sinal de excesso é o mesmo sinal do nome vago citado antes: se o nome
do componente só faz sentido descrevendo onde ele fica, não o que ele faz, ele provavelmente
devia voltar a fazer parte do componente pai.
Outro erro é dividir por linha de código em vez de por responsabilidade. Um componente de 200 linhas que faz uma coisa só, com clareza, é mais fácil de manter do que cinco componentes de 40 linhas cada um acoplado aos outros quatro. Contagem de linhas é um sintoma a observar, não a régua que decide a divisão.
Componentização em React feita bem não é sobre ter poucos ou muitos arquivos. É sobre cada componente responder sozinho, sem contexto externo, à pergunta "o que isso faz". Se sua base de código já passou do ponto e cada mudança pequena vira um risco grande, fale com a gente para revisar a arquitetura de componentes do seu projeto.