Agosto 28, 2025

Avançado

Componentes Genéricos: A Arte de Não Reinventar a Roda (Parte 1)

"Se você está copiando e colando código, você está fazendo algo errado" - Todo desenvolvedor sênior, sempre.

O que diabos são Componentes Genéricos?

Antes de tudo, preciso deixar uma coisa bem clara: componentes genéricos não são um conceito formal da computação. Não existe um paper acadêmico ou um livro sagrado que defina o que é um componente genérico. Isso é mais uma daquelas boas práticas que a comunidade desenvolvedora criou para não enlouquecer.

Imagine que você está construindo uma casa. Você não vai inventar uma nova forma de fazer uma porta toda vez que precisar de uma, certo? Você usa o mesmo padrão, mas adapta o tamanho, a cor, o material. É exatamente isso que fazemos com componentes genéricos.

Mas vamos além da analogia da casa. Pense em como você organiza sua cozinha: você tem um conjunto de facas, mas cada uma tem um propósito específico. A faca de pão é diferente da faca de carne, mas ambas seguem o mesmo princípio básico de corte. Componentes genéricos funcionam da mesma forma: eles mantêm a essência, mas se adaptam ao contexto.

A chave aqui é entender que não estamos criando um componente que resolve todos os problemas do mundo. Estamos criando um componente que resolve um problema específico de forma reutilizável. É a diferença entre uma faca suíça (que faz tudo, mas nada bem) e um conjunto de facas especializadas (cada uma faz uma coisa perfeitamente).

Por que Componentes Genéricos são uma Mão na Roda?

1. DRY (Dont Repeat Yourself)

Se você já escreveu "não repita código" em algum lugar do seu projeto, parabéns! Você já entendeu metade do conceito. Componentes genéricos são a materialização dessa filosofia.

Mas o que isso significa na prática? Imagine que você tem um formulário de cadastro de usuário e outro de cadastro de produto. Ambos precisam de campos de texto, validação e botões de ação. Sem componentes genéricos, você acaba duplicando toda essa lógica. Com componentes genéricos, você cria um campo de texto reutilizável e um botão reutilizável, e só precisa se preocupar com a lógica específica de cada formulário.

O DRY não é apenas sobre não repetir código, é sobre não repetir problemas. Quando você tem um bug em um componente duplicado, você precisa corrigir em todos os lugares. Com componentes genéricos, você corrige uma vez e resolve em todos os lugares.

Mas aqui está o ponto crucial: DRY não significa "nunca repita nada". Às vezes, duplicar um pouco de código é melhor do que criar um componente genérico que é difícil de entender e manter. A regra é: duplique quando a duplicação é mais clara do que a abstração.

2. Manutenção é uma Delícia

Quando você precisa mudar algo, muda em um lugar só. Não precisa caçar todos os botões do projeto para alterar a cor. É como ter um interruptor central que controla todas as luzes da casa.

Mas vamos pensar em um cenário real: imagine que seu designer decide que todos os botões primários devem ter uma sombra mais sutil. Se você tem botões espalhados por 20 componentes diferentes, você vai passar uma tarde inteira fazendo a mesma alteração. Com um componente genérico, você muda em um lugar e todos os botões se atualizam automaticamente.

E não é só sobre mudanças visuais. Pense em acessibilidade: se você precisa adicionar suporte a leitores de tela em todos os botões, fazer isso em um componente genérico é muito mais eficiente do que ir atrás de cada instância individual.

A manutenção também inclui debugging. Quando você tem um problema com um comportamento específico, é muito mais fácil investigar um componente centralizado do que rastrear o mesmo problema em 15 lugares diferentes. Você pode colocar logs, breakpoints e testes em um lugar só.

3. Consistência Visual

Seus usuários não vão ficar confusos vendo botões diferentes em cada página. É como ter um design system sem precisar pagar uma fortuna para uma consultoria.

A consistência visual vai muito além de "parecer bonito". Ela afeta diretamente a usabilidade da sua aplicação. Quando um usuário vê um botão azul em uma página, ele espera que botões azuis em outras páginas tenham o mesmo comportamento. Componentes genéricos garantem que essa expectativa seja sempre atendida.

Além disso, a consistência facilita o onboarding de novos desenvolvedores na equipe. Eles não precisam aprender 15 formas diferentes de fazer a mesma coisa. E, quando você está trabalhando em equipe, todos seguem os mesmos padrões, o que reduz a confusão e melhora a qualidade do código.

Mas a consistência também tem um lado negativo: se você comete um erro no componente genérico, esse erro se propaga para todos os lugares onde ele é usado. É por isso que testes são fundamentais para componentes genéricos.

Exemplos Práticos (Porque teoria sem prática é só conversa fiada)

React: O Rei dos Componentes

Vamos começar com um exemplo simples mas poderoso. Imagine que você tem botões espalhados por toda a aplicação:

// ❌ Antes: Cada botão era um filho único
<button style={{ backgroundColor: "#007bff", color: "white", padding: "10px 20px" }}>
  Salvar
</button>

<button style={{ backgroundColor: "#dc3545", color: "white", padding: "10px 20px" }}>
  Deletar
</button>

Agora, com um componente genérico:

// ✅ Depois: Um componente que resolve tudo
<Button variant="primary">Salvar</Button>
<Button variant="danger">Deletar</Button>

O componente Button internamente gerencia todos os estilos, variantes e comportamentos. Você só precisa se preocupar com o que o botão deve fazer, não com como ele deve parecer.

Angular: O Framework que Gosta de Decorar Tudo

No Angular, a situação é similar. Você pode ter inputs com validação espalhados por vários formulários:

// ❌ Antes: Cada input era uma obra de arte única
<input type="text" placeholder="Nome" class="form-control" [(ngModel)]="nome">
<div class="invalid-feedback" *ngIf="nomeInvalido">Nome é obrigatório</div>

<input type="email" placeholder="Email" class="form-control" [(ngModel)]="email">
<div class="invalid-feedback" *ngIf="emailInvalido">Email inválido</div>

Com um componente genérico:

// ✅ Depois: Um input que resolve tudo
<app-form-input placeholder="Nome" [(value)]="nome" [validation]="validarNome"></app-form-input>
<app-form-input type="email" placeholder="Email" [(value)]="email" [validation]="validarEmail"></app-form-input>

O componente app-form-input gerencia internamente a validação, os estilos de erro e a lógica de input. Você só precisa passar a função de validação específica para cada campo.

Conclusão: Por que Vale a Pena o Esforço?

Componentes genéricos podem parecer um trabalho extra no início; você tem que pensar na abstração, criar interfaces flexíveis e testar diferentes cenários. Mas, como vimos nos exemplos, o retorno é imediato e duradouro.

O que você ganha:

  • Tempo: Não precisa mais reescrever a mesma lógica 15 vezes
  • Qualidade: Menos bugs porque a lógica está centralizada
  • Flexibilidade: Mudanças globais em um só lugar
  • Equipe: Novos devs aprendem mais rápido

O que você perde:

  • Algumas horas no início para criar o componente
  • A "liberdade" de fazer cada botão de forma diferente (spoiler: isso não é liberdade, é bagunça)

É como investir em uma ferramenta de qualidade: custa um pouco mais no início, mas você a usa por anos e ela nunca te deixa na mão. Componentes genéricos são essas ferramentas do desenvolvimento frontend.


Na próxima parte, vamos falar sobre quando usar componentes genéricos, quando NÃO usar e o famoso caso dos filtros genéricos que deu tudo errado. Fique ligado!

Post Autor

Leonardo Henrique

Leonardo Henrique

E aí! Sou o Leonardo Henrique, mas muita gente me conhece como "Leozinho do Front" — culpa da minha paixão por Front-End. Trabalho como desenvolvedor Full Stack, com bastante experiência em Angular, um carinho especial por React e, agora, me aventurando com Vue. Curto demais jogos e animes, e um dia ainda quero me aventurar na área de games.