Setembro 11, 2025
Avançado
Componentes Genéricos: A Arte de Não Reinventar a Roda (Parte 2)
Nesta parte, vamos descobrir quando usar e quando NÃO usar componentes genéricos, incluindo o famoso caso dos filtros genéricos que deu tudo errado. Também vamos explorar casos específicos em que a generalização pode ser problemática.
Resumo da Parte 1
Na parte 1 sobre Componentes Genéricos: A Arte de Não Reinventar a Roda, exploramos os fundamentos dos componentes genéricos:
-
O que são: ferramentas reutilizáveis que resolvem problemas específicos, não conceitos formais da computação.
-
Por que usar: DRY (não repetir código), facilita manutenção, garante consistência visual.
-
Exemplos práticos: Vimos como transformar botões e inputs duplicados em componentes genéricos em React e Angular.
💡 Se você não leu a Parte 1, clique aqui para ler primeiro e entender o contexto completo antes de continuar.
Quando Usar Componentes Genéricos?
✅ Use quando:
1. Você tem padrões que se repetem em várias partes da aplicação.
Isso é o mais óbvio, mas é importante entender o que significa "padrão". Não é apenas sobre aparência visual, é sobre comportamento, estrutura e lógica. Se você está escrevendo a mesma validação de e-mail em 5 lugares diferentes, é hora de criar um componente genérico.
Mas cuidado: não confunda "padrão" com "coincidência". Se dois componentes parecem similares mas têm propósitos fundamentalmente diferentes, forçar uma generalização pode criar mais problemas do que resolver.
2. Quer manter consistência visual e comportamental.
A consistência não é apenas estética. Ela afeta a experiência do usuário e a manutenibilidade do código. Se você quer que todos os botões de confirmação tenham o mesmo comportamento, um componente genérico é a solução.
3. Precisa facilitar a manutenção futura.
Pense que, no futuro, quando você precisar mudar algo, prefere alterar em um lugar ou em 20? Componentes genéricos são um investimento no futuro do seu código.
4. Está construindo um design system.
Se você está criando uma biblioteca de componentes para sua equipe ou empresa, componentes genéricos são essenciais. Eles garantem que todos sigam os mesmos padrões.
❌ Não use quando:
1. O componente é usado apenas uma vez.
Não force a generalização. Se algo é realmente único e específico, deixe como está. Componentes genéricos são ferramentas, não regras absolutas.
2. A lógica é tão específica que não faz sentido generalizar.
Às vezes, tentar criar um componente genérico para algo muito específico pode resultar em um componente confuso e difícil de usar. É melhor ter um componente específico e bem definido do que um genérico confuso.
3. Você está criando um componente "Frankenstein" que tenta fazer tudo.
Este é um erro comum. Um componente que tem 50 props diferentes e tenta resolver todos os problemas do mundo acaba sendo difícil de usar e manter. Às vezes é melhor ter vários componentes menores e específicos.
O Caso dos Filtros Genéricos: Um Exemplo do que NÃO Fazer
Aqui está uma experiência real que ilustra perfeitamente quando NÃO usar componentes genéricos. Em um sistema em que trabalhei, havia um filtro genérico que tentava resolver todos os problemas de filtragem do mundo. O resultado foi um desastre.
O filtro genérico tinha:
- Lógica de filtragem genérica para todos os tipos de dados;
- Gerenciamento de dependências entre campos;
- Requisições HTTP automáticas;
- Validação genérica;
- Estado global compartilhado.
🚨 Os problemas que surgiram:
Complexidade excessiva: O componente tinha 30+ props e era impossível de entender.
Acoplamento forte: mudar um filtro afetava outros filtros em outras telas.
Debugging infernal: quando algo dava errado, era difícil rastrear o problema.
Performance ruim: O componente fazia requisições desnecessárias.
Manutenção impossível: ninguém queria mexer no código por medo de quebrar tudo.
✅ A solução correta:
Em vez de um filtro genérico, criamos elementos de filtro genéricos:
// ✅ Elementos genéricos que se combinam
<FilterContainer>
<FilterInput
label="Nome"
placeholder="Digite o nome..."
value={filters.nome}
onChange={(value) => setFilters({ ...filters, nome: value })}
/>
<FilterSelect
label="Categoria"
options={categories}
value={filters.categoria}
onChange={(value) => setFilters({ ...filters, categoria: value })}
/>
<FilterDateRange
label="Período"
startDate={filters.dataInicio}
endDate={filters.dataFim}
onChange={(start, end) =>
setFilters({ ...filters, dataInicio: start, dataFim: end })
}
/>
<FilterActions>
<Button onClick={handleFilter}>Filtrar</Button>
<Button variant="secondary" onClick={handleClear}>
Limpar
</Button>
</FilterActions>
</FilterContainer>
🎯 Por que essa abordagem é melhor:
Responsabilidade única: cada elemento faz uma coisa bem.
Composição natural: os elementos se combinam para criar filtros complexos.
Flexibilidade: cada filtro pode ter sua própria lógica específica.
Manutenibilidade: mudanças em um elemento não afetam outros.
Testabilidade: cada elemento pode ser testado independentemente.
Quando NÃO Usar Componentes Genéricos
1. Lógica de Negócio Complexa.
Se o componente tem lógica de negócio específica (como regras de validação complexas, cálculos específicos ou integrações com APIs específicas), ele provavelmente não deve ser genérico.
Um exemplo ruim:
// ❌ Tentando tornar genérico algo que é específico
<BusinessLogicComponent
businessRules={complexRules}
apiEndpoints={endpoints}
validationSchema={schema}
calculationEngine={engine}
/>
Agora, vamos ver um bom exemplo de como poderíamos fazer isso:
// ✅ Componentes específicos para cada caso
<UserRegistrationForm />
<ProductCatalogFilters />
<OrderCalculationWidget />
2. Estados Muito Específicos
Se o componente gerencia um estado que é único para um contexto específico, ele não deve ser genérico.
Um exemplo ruim:
// ❌ Estado específico em componente genérico
<GenericForm
state={userState}
setState={setUserState}
validation={userValidation}
apiCall={updateUser}
/>
Novamente, vamos ver um bom exemplo de como poderíamos fazer isso:
// ✅ Estado específico em componente específico
<UserProfileForm />
3. Dependências Externas Complexas
Se o componente depende de muitas bibliotecas externas ou tem muitas dependências, ele pode não ser um bom candidato para generalização.
Conclusão: O Equilíbrio entre Flexibilidade e Simplicidade
Componentes genéricos são como uma faca de dois gumes: quando bem usados, eles são ferramentas poderosas que salvam tempo e garantem consistência. Quando mal usados, eles se tornam monstros que complicam mais do que ajudam.
A lição mais importante desta parte:
- Generalize o que é realmente comum: botões, inputs, modais básicos.
- Mantenha específico o que é único: lógica de negócio, estados complexos, filtros especializados.
- Prefira composição a configuração: vários componentes pequenos que se combinam são melhores que um componente gigante com 50 props.
O caso dos filtros genéricos nos ensinou que menos é mais. Em vez de tentar criar um componente que resolve tudo, é melhor criar componentes que fazem uma coisa bem e se combinam naturalmente.
Lembre-se: componentes genéricos devem simplificar sua vida, não complicá-la. Se você está gastando mais tempo configurando o componente genérico do que seria necessário para criar algo específico, você está fazendo errado.
Na próxima parte, vamos falar sobre as boas práticas para criar componentes genéricos eficazes e um exemplo prático de modal genérico. Não perca!
Post Autor

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.