JavaScript Avançado

Padrões Avançados em React: Compound Components, Render Props e HOCs na Prática

6 min de leitura

Padrões Avançados em React: Compound Components, Render Props e HOCs na Prática

Compound Components Compound Components é um padrão onde componentes trabalham em conjunto para gerenciar estado compartilhado. Cada componente filho é simples, mas juntos formam uma unidade funcional completa. Este padrão melhora a legibilidade do código e oferece flexibilidade sem expor lógica complexa. O segredo está em usar ou Context API para compartilhar estado entre componentes irmãos. Veja um exemplo prático de um componente de Acordeão: A vantagem é que o usuário controla a estrutura HTML sem lidar com props complexas. Mantém a interface clara e intuitiva. Render Props Render Props é uma técnica onde um componente recebe uma função como prop, que retorna JSX. Essa função tem acesso ao estado interno do componente, permitindo máxima flexibilidade sem precisar criar componentes derivados. É especialmente útil para compartilhar lógica entre componentes que renderizam de formas diferentes. Aqui está um exemplo de um componente que gerencia estado de mouse: O padrão oferece total controle sobre como os dados são renderizados. Porém, pode levar

<h2>Compound Components</h2>

<p>Compound Components é um padrão onde componentes trabalham em conjunto para gerenciar estado compartilhado. Cada componente filho é simples, mas juntos formam uma unidade funcional completa. Este padrão melhora a legibilidade do código e oferece flexibilidade sem expor lógica complexa.</p>

<p>O segredo está em usar <code>React.cloneElement</code> ou Context API para compartilhar estado entre componentes irmãos. Veja um exemplo prático de um componente de Acordeão:</p>

<pre><code class="language-jsx">const Accordion = ({ children }) =&gt; {

const [activeId, setActiveId] = React.useState(null);

return (

&lt;div className=&quot;accordion&quot;&gt;

{React.Children.map(children, child =&gt;

React.cloneElement(child, { activeId, setActiveId })

)}

&lt;/div&gt;

);

};

const AccordionItem = ({ id, title, children, activeId, setActiveId }) =&gt; {

const isActive = activeId === id;

return (

&lt;div className=&quot;accordion-item&quot;&gt;

&lt;button onClick={() =&gt; setActiveId(isActive ? null : id)}&gt;

{title}

&lt;/button&gt;

{isActive &amp;&amp; &lt;div className=&quot;accordion-content&quot;&gt;{children}&lt;/div&gt;}

&lt;/div&gt;

);

};

// Uso

&lt;Accordion&gt;

&lt;AccordionItem id=&quot;1&quot; title=&quot;Seção 1&quot;&gt;Conteúdo 1&lt;/AccordionItem&gt;

&lt;AccordionItem id=&quot;2&quot; title=&quot;Seção 2&quot;&gt;Conteúdo 2&lt;/AccordionItem&gt;

&lt;/Accordion&gt;</code></pre>

<p>A vantagem é que o usuário controla a estrutura HTML sem lidar com props complexas. Mantém a interface clara e intuitiva.</p>

<h2>Render Props</h2>

<p>Render Props é uma técnica onde um componente recebe uma função como prop, que retorna JSX. Essa função tem acesso ao estado interno do componente, permitindo máxima flexibilidade sem precisar criar componentes derivados. É especialmente útil para compartilhar lógica entre componentes que renderizam de formas diferentes.</p>

<p>Aqui está um exemplo de um componente que gerencia estado de mouse:</p>

<pre><code class="language-jsx">const MouseTracker = ({ children }) =&gt; {

const [position, setPosition] = React.useState({ x: 0, y: 0 });

const handleMouseMove = (e) =&gt; {

setPosition({ x: e.clientX, y: e.clientY });

};

return (

&lt;div onMouseMove={handleMouseMove} style={{ height: &#039;100vh&#039; }}&gt;

{children(position)}

&lt;/div&gt;

);

};

// Uso

&lt;MouseTracker&gt;

{({ x, y }) =&gt; (

&lt;div&gt;

Posição do mouse: X={x}, Y={y}

&lt;div style={{ left: x, top: y, position: &#039;absolute&#039; }}&gt;🎯&lt;/div&gt;

&lt;/div&gt;

)}

&lt;/MouseTracker&gt;</code></pre>

<p>O padrão oferece total controle sobre como os dados são renderizados. Porém, pode levar ao &quot;callback hell&quot; se mal estruturado. Use Render Props quando precisar de máxima flexibilidade de renderização.</p>

<h2>Higher-Order Components (HOCs)</h2>

<p>Um HOC é uma função que recebe um componente e retorna um novo componente aprimorado com funcionalidade adicional. É um padrão poderoso para reutilizar lógica, mas deve ser usado com cuidado pois pode complicar a rastreabilidade de props. Ideal para adicionar comportamentos transversais como autenticação ou temas globais.</p>

<p>Veja um exemplo prático de HOC para autenticação:</p>

<pre><code class="language-jsx">const withAuth = (WrappedComponent) =&gt; {

return (props) =&gt; {

const [isAuthenticated, setIsAuthenticated] = React.useState(false);

React.useEffect(() =&gt; {

// Simular verificação de autenticação

const token = localStorage.getItem(&#039;authToken&#039;);

setIsAuthenticated(!!token);

}, []);

if (!isAuthenticated) {

return &lt;div&gt;Acesso negado. Faça login primeiro.&lt;/div&gt;;

}

return &lt;WrappedComponent {...props} /&gt;;

};

};

const Dashboard = () =&gt; &lt;h1&gt;Bem-vindo ao Dashboard&lt;/h1&gt;;

const ProtectedDashboard = withAuth(Dashboard);

// Uso

&lt;ProtectedDashboard /&gt;</code></pre>

<p>HOCs funcionam bem para lógica transversal, mas a composição de múltiplos HOCs pode criar problemas de performance e readability. Considere usar Hooks customizados como alternativa mais moderna.</p>

<h3>Comparação: Quando Usar Cada Um</h3>

<ul>

<li><strong>Compound Components</strong>: Interface clara, múltiplos componentes relacionados, máximo controle estrutural.</li>

<li><strong>Render Props</strong>: Compartilhar estado dinamicamente, diferentes formas de renderizar dados.</li>

<li><strong>HOCs</strong>: Adicionar funcionalidade a componentes existentes, lógica transversal como logging ou autenticação.</li>

</ul>

<p>O React moderno privilegia <strong>Custom Hooks</strong> sobre esses padrões, mas todos ainda têm casos de uso válidos. A escolha depende da complexidade, legibilidade e manutenibilidade do seu projeto.</p>

<h2>Conclusão</h2>

<p>Os três padrões avançados em React—Compound Components, Render Props e HOCs—oferecem formas elegantes de gerenciar complexidade. Compound Components priorizam clareza estrutural; Render Props oferecem máxima flexibilidade; HOCs adicionam funcionalidade transversal. Domine-os não para usá-los em tudo, mas para escolher a solução certa em cada contexto. Na prática moderna, combine com Custom Hooks para código mais legível e eficiente.</p>

<h2>Referências</h2>

<ul>

<li><a href="https://react.dev/reference/react/cloneElement" target="_blank" rel="noopener noreferrer">React Documentation - Higher-Order Components</a></li>

<li><a href="https://kentcdodds.com/blog/advanced-react-patterns" target="_blank" rel="noopener noreferrer">Advanced React Patterns - Kent C. Dodds</a></li>

<li><a href="https://react.dev/learn" target="_blank" rel="noopener noreferrer">Render Props Pattern - Official React Docs</a></li>

<li><a href="https://blog.logrocket.com" target="_blank" rel="noopener noreferrer">Compound Components Explained - LogRocket</a></li>

<li><a href="https://patterns.dev/posts/compound-pattern" target="_blank" rel="noopener noreferrer">React Design Patterns - Patterns.dev</a></li>

</ul>

Comentários

Mais em JavaScript Avançado

O que Todo Dev Deve Saber sobre Redis com Node.js: Cache, Pub/Sub, Filas e Session Store
O que Todo Dev Deve Saber sobre Redis com Node.js: Cache, Pub/Sub, Filas e Session Store

Redis e Node.js: Fundamentos Essenciais Redis é um banco de dados em memória...

Formulários Complexos em React: React Hook Form e Zod Validation na Prática
Formulários Complexos em React: React Hook Form e Zod Validation na Prática

Por Que React Hook Form e Zod Juntos? Quando você trabalha com formulários co...

AbortController e Cancelamento de Operações Assíncronas: Do Básico ao Avançado
AbortController e Cancelamento de Operações Assíncronas: Do Básico ao Avançado

AbortController: Dominando o Cancelamento de Operações Assíncronas O é uma AP...