Evitando Prop Drilling com o Pattern de Composition
Como desenhar componentes React de forma mais limpa, mantendo responsabilidades separadas e evitando passagem excessiva de props.
1) Contextualizando o problema: prop drilling e seus impactos
Prop drilling ocorre quando precisamos passar props por várias camadas de componentes para alcançar um componente filho que realmente
utiliza aquele dado ou comportamento. Mesmo que a API pareça simples, esse padrão aumenta acoplamento, dificulta a reutilização
e torna a manutenção dolorosa conforme a base de código cresce.
A ideia que defendo é reduzir esse acoplamento deslocando a responsabilidade de composição para padrões que permitem
construir componentes através de unidades menores e combináveis, sem que cada camada precise conhecer a pilha de props de cima para baixo.
2) O que é o pattern de composition?
O pattern de composition foca em criar componentes que são, por natureza, composáveis. Em vez de passar props
para todos os níveis, você monta a interface a partir de partes menores (slots) que assumem responsabilidade de
renderização. Em React, isso se materializa via:
- Componentes com subcomponentes (slots) como Header, Body, Footer.
- Render props ou funções passadas como filhos para fornecer conteúdo sob demanda.
- Padrões de ergonomia como as prop e composição baseada em funções para extensões sem quebrar o encapsulamento.
Dica prática: prefira compor a UI com partes independentes, em vez de passar muitas props profundas.
3) Como aplicar: padrões de composição na prática
Abaixo apresento duas formas eficazes de evitar prop drilling com o pattern de composition:
- Slots/padrão de subcomponentes estáticos:
Crio um componente base que expõe partes específicas para serem preenchidas pelos filhos, mantendo a API enxuta. - Render props simplificadas para conteúdo dinâmico:
Permito que o usuário forneça conteúdo via props ou via filhos, sem exigir que passe props de estado por várias camadas.
// Exemplo 1: Card com slots (Header, Body, Footer)
function Card({ children }) {
return {children};
}
Card.Header = function CardHeader({ children }) {
return {children};
}
Card.Body = function CardBody({ children }) {
return {children};
}
Card.Footer = function CardFooter({ children }) {
return {children};
};
// Uso:
<Card>
<Card.Header>Título do Card</Card.Header>
<Card.Body>Conteúdo interno que não faz parte da API externa</Card.Body>
<Card.Footer>
<button>Ação</button>
</Card.Footer>
</Card>
// Exemplo 2: Pattern "Modal" com composição
function Modal({ children }) {
return (
<div role="dialog" aria-modal="true" className="modal">
{children}
</div>
);
}
Modal.Header = function ModalHeader({ children }) {
return <div className="modal-header">{children}</div>;
};
Modal.Body = function ModalBody({ children }) {
return <div className="modal-body">{children}</div>;
};
Modal.Footer = function ModalFooter({ children }) {
return <div className="modal-footer">{children}</div>;
};
// Uso:
<Modal>
<Modal.Header>Confirmação</Modal.Header>
<Modal.Body>Deseja realmente prosseguir com esta ação?</Modal.Body>
<Modal.Footer>
<button>Cancelar</button>
<button>Confirmar</button>
</Modal.Footer>
</Modal>
4) Benefícios, trade-offs e boas práticas
Aplicar o pattern de composition traz ganhos claros:
- Menor acoplamento entre camadas; cada componente expõe apenas o necessário.
- Reutilização mais simples: é possível combinar componentes de maneiras novas sem refatorar props existentes.
- Melhor legibilidade da UI: estrutura fica explícita pela composição de partes, não pela passagem de props profundas.
Atenção a trade-offs: a flexibilidade adicional pode exigir mais planejamento inicial no design de APIs, e algumas combinações
podem exigir documentação clara sobre as possibilidades de composição.
Conclusão rápida
O pattern de composition é uma ferramenta poderosa para evitar prop drilling e manter componentes pequenos, coesos e
fáceis de testar. Ao oferecer slots para composição de partes da UI e usar render props de forma contida, você cria
uma base que cresce de forma sustentável sem perder clareza.
Personalize os padrões conforme o seu ecossistema: React, Preact ou outras libs de view podem se beneficiar de estruturas
semelhantes de composição.
Sugestões de leitura
Sou Apaixonado pela programação e estou trilhando o caminho de ter cada diz mais conhecimento e trazer toda minha experiência vinda do Design para a programação resultando em layouts incríveis e idéias inovadoras! Conecte-se Comigo!