<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Gabriel Teixeira da Silva</title>
    <description>The latest articles on DEV Community by Gabriel Teixeira da Silva (@gabrielteixeira44).</description>
    <link>https://dev.to/gabrielteixeira44</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1001137%2Fc17b89ae-5054-497b-8b3f-d01f0e602b9f.jpg</url>
      <title>DEV Community: Gabriel Teixeira da Silva</title>
      <link>https://dev.to/gabrielteixeira44</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gabrielteixeira44"/>
    <language>en</language>
    <item>
      <title>Hoje explorei como o Compound Pattern e a Composition API ajudam a criar componentes flexíveis, reutilizáveis e altamente configuráveis em aplicações modernas.</title>
      <dc:creator>Gabriel Teixeira da Silva</dc:creator>
      <pubDate>Tue, 09 Dec 2025 14:21:19 +0000</pubDate>
      <link>https://dev.to/gabrielteixeira44/hoje-explorei-como-o-compound-pattern-e-a-composition-api-ajudam-a-criar-componentes-flexiveis-9pm</link>
      <guid>https://dev.to/gabrielteixeira44/hoje-explorei-como-o-compound-pattern-e-a-composition-api-ajudam-a-criar-componentes-flexiveis-9pm</guid>
      <description>&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/gabrielteixeira44/criando-componentes-flexiveis-com-compound-pattern-e-composition-3eph" class="crayons-story__hidden-navigation-link"&gt;Criando Componentes Flexíveis com Compound Pattern e Composition&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/gabrielteixeira44" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1001137%2Fc17b89ae-5054-497b-8b3f-d01f0e602b9f.jpg" alt="gabrielteixeira44 profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/gabrielteixeira44" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Gabriel Teixeira da Silva
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Gabriel Teixeira da Silva
                
              
              &lt;div id="story-author-preview-content-3084718" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/gabrielteixeira44" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1001137%2Fc17b89ae-5054-497b-8b3f-d01f0e602b9f.jpg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Gabriel Teixeira da Silva&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/gabrielteixeira44/criando-componentes-flexiveis-com-compound-pattern-e-composition-3eph" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Dec 6 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/gabrielteixeira44/criando-componentes-flexiveis-com-compound-pattern-e-composition-3eph" id="article-link-3084718"&gt;
          Criando Componentes Flexíveis com Compound Pattern e Composition
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/gabrielteixeira44/criando-componentes-flexiveis-com-compound-pattern-e-composition-3eph" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;1&lt;span class="hidden s:inline"&gt; reaction&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/gabrielteixeira44/criando-componentes-flexiveis-com-compound-pattern-e-composition-3eph#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            5 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;




</description>
    </item>
    <item>
      <title>Criando Componentes Flexíveis com Compound Pattern e Composition</title>
      <dc:creator>Gabriel Teixeira da Silva</dc:creator>
      <pubDate>Sat, 06 Dec 2025 14:31:52 +0000</pubDate>
      <link>https://dev.to/gabrielteixeira44/criando-componentes-flexiveis-com-compound-pattern-e-composition-3eph</link>
      <guid>https://dev.to/gabrielteixeira44/criando-componentes-flexiveis-com-compound-pattern-e-composition-3eph</guid>
      <description>&lt;p&gt;Se você trabalha com React há algum tempo, provavelmente já se deparou com o dilema do &lt;strong&gt;"Componente Monolítico"&lt;/strong&gt;. Aquele componente que começa inofensivo, mas à medida que o projeto cresce, ele começa a aceitar dezenas de &lt;em&gt;props&lt;/em&gt; para tratar cada pequena variação de layout e lógica.&lt;/p&gt;

&lt;p&gt;Hoje, vamos falar sobre como evitar isso usando dois padrões poderosos: &lt;strong&gt;Compound Components&lt;/strong&gt; e &lt;strong&gt;Composition Pattern&lt;/strong&gt;, sem deixar de lado a &lt;strong&gt;Acessibilidade&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Vamos usar um exemplo clássico de UI: um &lt;strong&gt;Accordion&lt;/strong&gt; (lista expansível), mas a lógica se aplica a Modais, Tabs, Menus e muito mais.&lt;/p&gt;

&lt;h2&gt;
  
  
  O Problema: A Abordagem Rígida
&lt;/h2&gt;

&lt;p&gt;Imagine que você precisa criar um Accordion. A abordagem iniciante geralmente centraliza tudo na configuração:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ❌ O jeito rígido (Componente Monolítico)&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Accordion&lt;/span&gt;
  &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;O que é React?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Uma lib JS...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Acessibilidade&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;É essencial...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;allowMultiple&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;iconPosition&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"right"&lt;/span&gt;
  &lt;span class="na"&gt;titleColor&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"blue"&lt;/span&gt;
  &lt;span class="c1"&gt;// E se eu quiser colocar um ícone SVG no título?&lt;/span&gt;
  &lt;span class="c1"&gt;// E se eu quiser um botão dentro do conteúdo?&lt;/span&gt;
  &lt;span class="c1"&gt;// Mais props... 🤯&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O problema aqui é que a configuração (&lt;code&gt;data&lt;/code&gt;) está misturada com a UI. Se o designer decidir que o título do segundo item precisa ser vermelho, você terá que "sujar" seu código com mais props condicionais.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Solução: Compound Components + Acessibilidade
&lt;/h2&gt;

&lt;p&gt;O padrão &lt;strong&gt;Compound Component&lt;/strong&gt; permite que componentes trabalhem juntos, compartilhando estado implicitamente, enquanto a &lt;strong&gt;Composition&lt;/strong&gt; deixa o desenvolvedor decidir &lt;em&gt;onde&lt;/em&gt; renderizar cada parte.&lt;/p&gt;

&lt;p&gt;Além disso, ao criarmos nossos próprios componentes, temos a responsabilidade de torná-los acessíveis. Um Accordion sem atributos ARIA (&lt;code&gt;aria-expanded&lt;/code&gt;, &lt;code&gt;aria-controls&lt;/code&gt;) é invisível para usuários que dependem de leitores de tela.&lt;/p&gt;

&lt;p&gt;Queremos chegar neste resultado (DX - Developer Experience):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ✅ O jeito flexível e acessível&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Accordion&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Accordion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"item-1"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Accordion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Trigger&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;O que é React?&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Accordion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Trigger&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Accordion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      Uma biblioteca JavaScript para criar interfaces...
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Accordion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Accordion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Accordion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"item-2"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Accordion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Trigger&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Acessibilidade&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;IconeAcessibilidade&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt; 
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Accordion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Trigger&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Accordion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Saiba mais&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Accordion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Accordion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Accordion&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Mão na Massa: Implementando o Padrão
&lt;/h2&gt;

&lt;p&gt;Vamos construir isso usando React Context, Hooks e &lt;code&gt;useId&lt;/code&gt; para garantir a acessibilidade.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Criando o Contexto Principal
&lt;/h3&gt;

&lt;p&gt;Primeiro, o estado global do Accordion.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ReactNode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Definindo o formato do nosso contexto&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;AccordionContextType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;openItem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;toggleItem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AccordionContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createContext&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;AccordionContextType&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useAccordion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;AccordionContext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Os componentes do Accordion devem estar dentro de &amp;lt;Accordion /&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. O Componente Pai (Root)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;AccordionProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ReactNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AccordionRoot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;AccordionProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;openItem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setOpenItem&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;toggleItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setOpenItem&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prev&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AccordionContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Provider&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;openItem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;toggleItem&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"accordion-root border rounded-md max-w-lg mx-auto"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;AccordionContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Provider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Os Sub-Componentes Inteligentes
&lt;/h3&gt;

&lt;p&gt;Aqui está o segredo da acessibilidade. Vamos gerar IDs únicos para vincular o botão (Trigger) ao conteúdo (Content), para que o leitor de tela saiba o que aquele botão controla.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O Item (Gerenciador de IDs):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Contexto para passar IDs e Valor para os filhos (Trigger e Content)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ItemContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createContext&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
  &lt;span class="nl"&gt;triggerId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
  &lt;span class="nl"&gt;contentId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AccordionItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ReactNode&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useId&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Gera um ID único para este item&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;triggerId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`accordion-trigger-&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contentId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`accordion-content-&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ItemContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Provider&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;triggerId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;contentId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"accordion-item border-b last:border-none p-2"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;ItemContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Provider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;O Gatilho (Trigger):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AccordionTrigger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ReactNode&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;openItem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;toggleItem&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useAccordion&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;itemContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ItemContext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;itemContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Trigger deve estar dentro de um Item&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;triggerId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;contentId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;itemContext&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isOpen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;openItem&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;
      &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;triggerId&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;aria-controls&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;contentId&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// Diz ao leitor de tela o que este botão controla&lt;/span&gt;
      &lt;span class="na"&gt;aria-expanded&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isOpen&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;    &lt;span class="c1"&gt;// Diz se está aberto ou fechado&lt;/span&gt;
      &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;toggleItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"flex justify-between w-full p-4 font-medium text-left hover:bg-gray-50 transition focus:outline-none focus:ring-2 focus:ring-blue-500"&lt;/span&gt;
    &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt; &lt;span class="na"&gt;aria-hidden&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isOpen&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;➖&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;➕&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;O Conteúdo (Content):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AccordionContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ReactNode&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;openItem&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useAccordion&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;itemContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ItemContext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;itemContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content deve estar dentro de um Item&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;triggerId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;contentId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;itemContext&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isOpen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;openItem&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isOpen&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; 
      &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;contentId&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"region"&lt;/span&gt; 
      &lt;span class="na"&gt;aria-labelledby&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;triggerId&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// Vincula de volta ao botão&lt;/span&gt;
      &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"p-4 text-gray-600 bg-white animate-fade-in"&lt;/span&gt;
    &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Finalizando a Composição
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Accordion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;AccordionRoot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AccordionItem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;Trigger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AccordionTrigger&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AccordionContent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Por que a Acessibilidade Importa?
&lt;/h2&gt;

&lt;p&gt;Quando criamos componentes customizados ("na unha"), perdemos a semântica nativa do HTML (como a tag &lt;code&gt;&amp;lt;details&amp;gt;&lt;/code&gt; e &lt;code&gt;&amp;lt;summary&amp;gt;&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Ao adicionar &lt;code&gt;aria-expanded&lt;/code&gt; e &lt;code&gt;aria-controls&lt;/code&gt;, garantimos que usuários que navegam via teclado ou leitores de tela tenham a mesma experiência que usuários visuais. &lt;strong&gt;Um componente bonito que não pode ser usado por todos é um componente incompleto.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Mas e o &lt;code&gt;&amp;lt;details&amp;gt;&lt;/code&gt; e &lt;code&gt;&amp;lt;summary&amp;gt;&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;Você deve estar se perguntando: "Por que escrever tanto código se o HTML5 já tem as tags &lt;code&gt;&amp;lt;details&amp;gt;&lt;/code&gt; e &lt;code&gt;&amp;lt;summary&amp;gt;&lt;/code&gt;?"&lt;/p&gt;

&lt;p&gt;Essa é uma ótima pergunta. O uso de tags nativas é sempre encorajado, pois garante acessibilidade e SEO "out-of-the-box". No entanto, criar um Accordion controlado via React (como fizemos acima) é necessário quando:&lt;/p&gt;

&lt;p&gt;Exclusividade de Abertura: Queremos que, ao abrir um item, os outros se fechem automaticamente. Fazer isso com  exige interceptar eventos e manipular o atributo open manualmente, o que nos traz de volta ao gerenciamento de estado.&lt;/p&gt;

&lt;p&gt;Animações Fluidas: Animar o fechamento de um elemento nativo &lt;code&gt;&amp;lt;details&amp;gt;&lt;/code&gt; ainda é complexo no CSS puro (devido à transição de height: auto). Com componentes React, temos controle total sobre o ciclo de vida da animação.&lt;/p&gt;

&lt;p&gt;Design System Rigoroso: Quando precisamos de total liberdade visual sem lutar contra os estilos padrão do User Agent (como o triângulo padrão do &lt;code&gt;&amp;lt;summary&amp;gt;&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Se o seu caso de uso é simples e não exige que um item feche o outro, vá de HTML nativo! Mas para construir componentes robustos de UI libraries, o padrão Compound oferece o controle que precisamos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Padrões de projeto como o &lt;strong&gt;Compound Components&lt;/strong&gt; são o segredo para bibliotecas robustas como &lt;em&gt;Radix UI&lt;/em&gt; e &lt;em&gt;Chakra UI&lt;/em&gt;. Eles oferecem o equilíbrio perfeito entre lógica encapsulada, liberdade de estilização e acessibilidade.&lt;/p&gt;

&lt;p&gt;Da próxima vez que for criar um componente reutilizável, lembre-se: separe a lógica da UI e nunca se esqueça dos usuários que não usam mouse.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>MVVM para Iniciantes: Desvendando o Padrão de Arquitetura</title>
      <dc:creator>Gabriel Teixeira da Silva</dc:creator>
      <pubDate>Thu, 09 Oct 2025 11:32:42 +0000</pubDate>
      <link>https://dev.to/gabrielteixeira44/mvvm-para-iniciantes-desvendando-o-padrao-de-arquitetura-2dna</link>
      <guid>https://dev.to/gabrielteixeira44/mvvm-para-iniciantes-desvendando-o-padrao-de-arquitetura-2dna</guid>
      <description>&lt;h1&gt;
  
  
  MVVM para Iniciantes: Desvendando o Padrão de Arquitetura
&lt;/h1&gt;

&lt;p&gt;A arquitetura &lt;strong&gt;MVVM&lt;/strong&gt; (&lt;em&gt;Model-View-ViewModel&lt;/em&gt;) é uma das abordagens mais populares e eficazes para organizar o código em aplicações modernas. Ela busca &lt;strong&gt;separar responsabilidades&lt;/strong&gt;, tornando o código mais limpo, testável e escalável — características essenciais em projetos de médio e grande porte.&lt;/p&gt;

&lt;p&gt;Neste artigo, vamos mergulhar no conceito de MVVM, entender suas camadas, vantagens e desafios, e ainda ver exemplos práticos para que você possa aplicar esse padrão em seus próprios projetos.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧭 O Que é o MVVM?
&lt;/h2&gt;

&lt;p&gt;O &lt;strong&gt;MVVM&lt;/strong&gt; é um padrão de arquitetura criado por &lt;strong&gt;John Gossman&lt;/strong&gt; em 2005, inicialmente para o framework &lt;strong&gt;Microsoft WPF (Windows Presentation Foundation)&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Com o passar dos anos, sua adoção se expandiu e hoje está presente em diversas tecnologias como &lt;strong&gt;Angular&lt;/strong&gt;, &lt;strong&gt;Vue&lt;/strong&gt;, &lt;strong&gt;React&lt;/strong&gt;, &lt;strong&gt;Flutter&lt;/strong&gt;, &lt;strong&gt;SwiftUI&lt;/strong&gt;, &lt;strong&gt;Jetpack Compose&lt;/strong&gt;, e até mesmo em frameworks backend que lidam com a camada de apresentação.&lt;/p&gt;

&lt;p&gt;O objetivo do MVVM é &lt;strong&gt;desacoplar a lógica da interface do usuário&lt;/strong&gt; da lógica de negócios e manipulação de dados.&lt;br&gt;&lt;br&gt;
Isso permite que desenvolvedores trabalhem em diferentes partes da aplicação sem interferir uns nos outros, além de facilitar testes unitários e manutenção.&lt;/p&gt;

&lt;p&gt;A estrutura básica é composta por três elementos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Model  ↔  ViewModel  ↔  View
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cada camada tem um papel claro e definido, como veremos a seguir.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧩 Entendendo as Camadas do MVVM
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Model — O Coração dos Dados&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;O &lt;strong&gt;Model&lt;/strong&gt; representa os dados da aplicação e a lógica de negócios.&lt;br&gt;&lt;br&gt;
Ele é responsável por acessar APIs, consultar bancos de dados, aplicar validações e regras do domínio.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Boas práticas:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Evite depender da UI;&lt;/li&gt;
&lt;li&gt;Centralize regras de negócio aqui;&lt;/li&gt;
&lt;li&gt;Mantenha o Model independente do framework utilizado.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Exemplo:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// models/User.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;strong&gt;2. View — A Interface do Usuário&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;View&lt;/strong&gt; é responsável apenas por &lt;strong&gt;exibir informações&lt;/strong&gt; e &lt;strong&gt;interagir com o usuário&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Ela observa o &lt;em&gt;ViewModel&lt;/em&gt; e reage automaticamente às mudanças, sem precisar lidar com regras de negócio.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Boas práticas:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Não coloque lógica de negócio aqui;&lt;/li&gt;
&lt;li&gt;Use &lt;em&gt;data binding&lt;/em&gt; sempre que possível;&lt;/li&gt;
&lt;li&gt;Deixe a View “burra”, focada apenas em apresentar dados.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Exemplo (Vue.js):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- UserView.vue --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;section&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;{{ user.name }}&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;{{ user.email }}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;strong&gt;3. ViewModel — O Elo Entre o Model e a View&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;O &lt;strong&gt;ViewModel&lt;/strong&gt; atua como intermediário entre o &lt;em&gt;Model&lt;/em&gt; e a &lt;em&gt;View&lt;/em&gt;.&lt;br&gt;&lt;br&gt;
Ele é responsável por preparar e transformar os dados vindos do Model para que possam ser exibidos na View.&lt;/p&gt;

&lt;p&gt;Em frameworks reativos, o ViewModel geralmente usa mecanismos como &lt;em&gt;observables&lt;/em&gt;, &lt;em&gt;reactive refs&lt;/em&gt; ou &lt;em&gt;state hooks&lt;/em&gt; para notificar a View sobre mudanças.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo (Vue + Composition API):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// viewmodels/useUserViewModel.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onMounted&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../models/User&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;useUserViewModel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/user/1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;onMounted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fetchUser&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fetchUser&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E na &lt;em&gt;View&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- UserView.vue --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"user"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;{{ user.name }}&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;{{ user.email }}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;setup&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useUserViewModel&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../viewmodels/useUserViewModel&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useUserViewModel&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔄 Ciclo de Comunicação MVVM
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;O &lt;strong&gt;usuário interage&lt;/strong&gt; com a View (clicando, digitando, etc.);&lt;/li&gt;
&lt;li&gt;A View &lt;strong&gt;envia comandos&lt;/strong&gt; ao ViewModel;&lt;/li&gt;
&lt;li&gt;O ViewModel &lt;strong&gt;processa&lt;/strong&gt; a ação e &lt;strong&gt;atualiza o Model&lt;/strong&gt;, se necessário;&lt;/li&gt;
&lt;li&gt;O Model &lt;strong&gt;retorna novos dados&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt;O ViewModel &lt;strong&gt;notifica&lt;/strong&gt; a View sobre a mudança;&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;View é atualizada automaticamente&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Esse fluxo cria uma &lt;strong&gt;camada de reatividade&lt;/strong&gt; natural, evitando a manipulação direta do DOM e deixando a aplicação mais previsível.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧪 Benefícios do MVVM
&lt;/h2&gt;

&lt;p&gt;✅ &lt;strong&gt;Separação de responsabilidades:&lt;/strong&gt; cada parte tem um papel claro.&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Facilidade de manutenção:&lt;/strong&gt; alterar uma camada não quebra outra.&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Alta testabilidade:&lt;/strong&gt; o ViewModel pode ser testado sem interface gráfica.&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Escalabilidade:&lt;/strong&gt; o projeto cresce sem virar uma bagunça.&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Reutilização de código:&lt;/strong&gt; o mesmo ViewModel pode alimentar diferentes Views.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚠️ Desvantagens e Desafios
&lt;/h2&gt;

&lt;p&gt;Nem tudo são flores! O MVVM também traz desafios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📉 &lt;strong&gt;Curva de aprendizado:&lt;/strong&gt; exige disciplina e organização.
&lt;/li&gt;
&lt;li&gt;🧩 &lt;strong&gt;Complexidade inicial:&lt;/strong&gt; pode parecer overkill em projetos pequenos.
&lt;/li&gt;
&lt;li&gt;🔄 &lt;strong&gt;Sincronização de estados:&lt;/strong&gt; requer atenção ao fluxo de dados para evitar inconsistências.
&lt;/li&gt;
&lt;li&gt;🧠 &lt;strong&gt;Testes mal definidos:&lt;/strong&gt; se o ViewModel ficar muito grande, o padrão se perde.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Dica:&lt;/strong&gt; mantenha o ViewModel enxuto, focado apenas em coordenar a lógica entre Model e View.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧱 MVVM vs MVC vs MVP
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Padrão&lt;/th&gt;
&lt;th&gt;Papel do Intermediário&lt;/th&gt;
&lt;th&gt;Comunicação&lt;/th&gt;
&lt;th&gt;Exemplo de uso&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MVC&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Controller&lt;/td&gt;
&lt;td&gt;View ↔ Controller ↔ Model&lt;/td&gt;
&lt;td&gt;Aplicações clássicas web e server-side&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MVP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Presenter&lt;/td&gt;
&lt;td&gt;View ↔ Presenter ↔ Model&lt;/td&gt;
&lt;td&gt;Aplicações Android antigas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MVVM&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ViewModel&lt;/td&gt;
&lt;td&gt;View ↔ Data Binding ↔ Model&lt;/td&gt;
&lt;td&gt;Apps reativos modernos (Vue, Angular, React, Flutter)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;O &lt;strong&gt;MVVM&lt;/strong&gt; se destaca justamente pela &lt;strong&gt;reatividade&lt;/strong&gt; e &lt;strong&gt;ligação automática de dados (data binding)&lt;/strong&gt;, algo que o MVC e o MVP não implementam de forma nativa.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Boas Práticas ao Usar MVVM
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;1. Mantenha o ViewModel simples:&lt;/strong&gt; nada de regras de negócio pesadas aqui.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2. Evite dependências diretas entre View e Model.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;3. Use observables, refs ou estados globais bem definidos.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;4. Organize pastas por funcionalidade:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;models/&lt;/code&gt; → entidades e regras de domínio
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;viewmodels/&lt;/code&gt; → lógica de exibição
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;views/&lt;/code&gt; → componentes visuais
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;5. Escreva testes para o ViewModel&lt;/strong&gt; (é onde mora a maior parte da lógica).&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  🚀 Conclusão
&lt;/h2&gt;

&lt;p&gt;O &lt;strong&gt;MVVM&lt;/strong&gt; é mais do que um padrão de arquitetura — é uma filosofia de desenvolvimento que preza pela &lt;strong&gt;clareza&lt;/strong&gt;, &lt;strong&gt;modularidade&lt;/strong&gt; e &lt;strong&gt;previsibilidade&lt;/strong&gt; do código.&lt;/p&gt;

&lt;p&gt;Ele te ajuda a construir aplicações robustas, com &lt;strong&gt;código sustentável&lt;/strong&gt;, fácil de &lt;strong&gt;evoluir&lt;/strong&gt; e &lt;strong&gt;testar&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Mesmo que no início pareça mais complexo, com o tempo, o MVVM se torna um aliado poderoso para qualquer desenvolvedor que deseja criar soluções escaláveis e bem estruturadas.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Comece pequeno: implemente um ViewModel em um projeto simples e observe como tudo começa a fazer sentido.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;✍️ &lt;strong&gt;Autor:&lt;/strong&gt; Gabriel Silva&lt;br&gt;&lt;br&gt;
💻 Engenheiro de Software | Foco em Arquitetura, Acessibilidade e Desenvolvimento Web&lt;br&gt;&lt;br&gt;
📚 &lt;em&gt;"Tentando escrever código limpo e acessível."&lt;/em&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>architecture</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>Por que Acessibilidade Importa? Entenda o Essencial para Apps Mais Inclusivos</title>
      <dc:creator>Gabriel Teixeira da Silva</dc:creator>
      <pubDate>Thu, 19 Jun 2025 22:48:38 +0000</pubDate>
      <link>https://dev.to/gabrielteixeira44/por-que-acessibilidade-importa-entenda-o-essencial-para-apps-mais-inclusivos-4goh</link>
      <guid>https://dev.to/gabrielteixeira44/por-que-acessibilidade-importa-entenda-o-essencial-para-apps-mais-inclusivos-4goh</guid>
      <description>&lt;h3&gt;
  
  
  Introdução
&lt;/h3&gt;

&lt;p&gt;Você já parou para pensar em como pessoas com diferentes tipos de deficiência usam aplicativos? Acessibilidade é um tema cada vez mais relevante no universo do desenvolvimento, mas ainda pouco explorado na prática. Segundo a Organização Mundial da Saúde, mais de 1 bilhão de pessoas no mundo têm algum tipo de deficiência. Ou seja, ao desenvolver aplicativos acessíveis, ampliamos o alcance do nosso produto, promovemos inclusão e melhoramos a experiência para todos.&lt;/p&gt;

&lt;h3&gt;
  
  
  O que significa um aplicativo acessível?
&lt;/h3&gt;

&lt;p&gt;Um aplicativo acessível é aquele que pode ser utilizado por todas as pessoas, independentemente de suas capacidades físicas, visuais, auditivas, motoras ou cognitivas. Isso vai além de cumprir uma lista de requisitos técnicos: trata-se de garantir autonomia e proporcionar uma experiência positiva para todos os usuários.&lt;/p&gt;

&lt;p&gt;Pense em situações do dia a dia, como um usuário com deficiência visual navegando por um app usando um leitor de tela, ou uma pessoa com mobilidade reduzida utilizando apenas o teclado ou gestos simples para acessar funcionalidades essenciais.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principais barreiras de acessibilidade em aplicativos
&lt;/h3&gt;

&lt;p&gt;No desenvolvimento de aplicativos, alguns obstáculos comuns acabam limitando o acesso de parte dos usuários, como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Baixo contraste de cores:&lt;/strong&gt; dificulta a leitura, principalmente para pessoas com baixa visão ou daltonismo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Textos pequenos ou ilegíveis:&lt;/strong&gt; dificultam a compreensão, especialmente para pessoas com deficiência visual.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Falta de suporte a leitores de tela:&lt;/strong&gt; impede que pessoas cegas ou com baixa visão utilizem o app.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Botões pequenos ou de difícil alcance:&lt;/strong&gt; prejudicam quem tem limitações motoras.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ausência de legendas em vídeos e descrições de imagens:&lt;/strong&gt; limita o acesso de pessoas surdas ou com deficiência auditiva.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fluxos complexos ou dependentes de gestos específicos:&lt;/strong&gt; podem excluir pessoas com deficiência cognitiva ou motora.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Boas práticas para tornar seu app mais acessível
&lt;/h3&gt;

&lt;p&gt;Existem práticas simples que, se adotadas desde o início do projeto, já fazem uma grande diferença:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Use cores com bom contraste:&lt;/strong&gt; Ferramentas online ajudam a verificar se as combinações de cores estão acessíveis.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Permita ajuste de tamanho da fonte:&lt;/strong&gt; Use unidades relativas e respeite as configurações de acessibilidade do sistema.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Descreva imagens e botões:&lt;/strong&gt; Sempre use textos alternativos (alt text) em imagens e nomes claros em botões.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Garanta navegação por teclado e leitores de tela:&lt;/strong&gt; Teste se todos os componentes podem ser acessados sem mouse (ou apenas por gestos simples).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Forneça legendas e transcrições:&lt;/strong&gt; Para conteúdos em áudio ou vídeo, legendas e transcrições são essenciais.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evite depender apenas de cor para transmitir informação:&lt;/strong&gt; Use ícones, textos ou padrões junto com cores.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Ferramentas e recursos para desenvolvedores
&lt;/h3&gt;

&lt;p&gt;Hoje, existem várias ferramentas para apoiar o desenvolvimento acessível:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lighthouse (Web), Axe, WAVE:&lt;/strong&gt; para análise automática de acessibilidade em aplicativos web.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accessibility Scanner (Android), Accessibility Inspector (iOS):&lt;/strong&gt; para verificar a acessibilidade em aplicativos mobile.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Documentações oficiais:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.android.com/guide/topics/ui/accessibility" rel="noopener noreferrer"&gt;Google Android Accessibility&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.apple.com/accessibility/" rel="noopener noreferrer"&gt;Apple Accessibility (iOS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.w3.org/WAI/" rel="noopener noreferrer"&gt;W3C Web Accessibility Initiative (WAI)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Além disso, comunidades como &lt;a href="https://www.a11yproject.com/" rel="noopener noreferrer"&gt;A11y Project&lt;/a&gt; oferecem conteúdo atualizado e dicas práticas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Benefícios de investir em acessibilidade
&lt;/h3&gt;

&lt;p&gt;Tornar seu aplicativo acessível traz vantagens que vão além do aspecto social:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Maior alcance de usuários:&lt;/strong&gt; Você inclui pessoas que, de outra forma, seriam excluídas do seu produto.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Melhora da experiência para todos:&lt;/strong&gt; Soluções acessíveis costumam ser mais intuitivas para qualquer pessoa.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cumprimento de legislações:&lt;/strong&gt; Em muitos países, incluindo o Brasil, já existem leis que exigem acessibilidade digital.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Valor para a marca:&lt;/strong&gt; Empresas inclusivas são melhor vistas pelo público e pelo mercado.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Conclusão
&lt;/h3&gt;

&lt;p&gt;Acessibilidade não é só uma tendência: é uma responsabilidade de todo desenvolvedor. Investir em aplicativos acessíveis é criar soluções mais justas, inovadoras e eficientes. Que tal dar o primeiro passo e começar a aplicar essas boas práticas nos seus projetos? Pequenas mudanças podem gerar grandes impactos na vida dos usuários!&lt;/p&gt;

&lt;h3&gt;
  
  
  Próximos passos e leituras recomendadas
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://acessibilidade.gov.br/" rel="noopener noreferrer"&gt;Acessibilidade Web na Prática – W3C Brasil&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cartilha.acessibilidade.gov.br/" rel="noopener noreferrer"&gt;Cartilha de Acessibilidade na Web – W3C&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.android.com/guide/topics/ui/accessibility" rel="noopener noreferrer"&gt;Guia de Acessibilidade para Desenvolvedores Android (Google)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.apple.com/accessibility/" rel="noopener noreferrer"&gt;Guia de Acessibilidade para iOS (Apple)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Quando Usar um Gerenciador de Estado no React? Minha Experiência na Prática</title>
      <dc:creator>Gabriel Teixeira da Silva</dc:creator>
      <pubDate>Mon, 20 Jan 2025 13:06:02 +0000</pubDate>
      <link>https://dev.to/gabrielteixeira44/quando-usar-um-gerenciador-de-estado-no-react-minha-experiencia-na-pratica-11o8</link>
      <guid>https://dev.to/gabrielteixeira44/quando-usar-um-gerenciador-de-estado-no-react-minha-experiencia-na-pratica-11o8</guid>
      <description>&lt;p&gt;Oi pessoal, tudo bem?&lt;br&gt;
Hoje quero compartilhar um pouco da minha experiência sobre quando é o momento ideal de usar uma biblioteca de gerenciamento de estado em aplicações React.&lt;/p&gt;

&lt;p&gt;Comecei a construir um backoffice usando Next.js 14 e, no início, não senti necessidade de implementar nenhuma biblioteca de gerenciamento de estado. Para algumas informações globais, utilizei o React Context, que resolveu bem problemas simples.&lt;/p&gt;

&lt;p&gt;Porém, conforme a aplicação cresceu, surgiu a necessidade de compartilhar informações entre componentes mais distantes. Foi aí que me deparei com o famoso problema do prop drilling. Esse cenário começou a tornar o código menos organizado e difícil de manter.&lt;/p&gt;

&lt;p&gt;A partir dessa experiência, percebi que estava na hora de considerar o uso de uma solução mais robusta, como Zustand, Redux ou Jotai.&lt;/p&gt;
&lt;h2&gt;
  
  
  O que é Prop Drilling e por que pode ser um problema?
&lt;/h2&gt;

&lt;p&gt;O prop drilling ocorre quando precisamos passar propriedades de um componente para outro que está distante na hierarquia, atravessando vários níveis intermediários. Em outras palavras, mesmo que um componente intermediário não utilize a propriedade, ele ainda precisa recebê-la e repassá-la para o próximo componente.&lt;/p&gt;

&lt;p&gt;Para ilustrar, imagine que temos uma estrutura de componentes como esta:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;App
 ├── Header
 │    └── UserMenu
 └── Main
      └── Sidebar
           └── UserProfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se quisermos passar informações de um usuário, como o nome, do componente App para o UserProfile, precisaríamos repassar a propriedade manualmente por todos os componentes intermediários:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function App() {
  const user = { name: "Gabriel" };

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;Header user={user} /&amp;gt;
      &amp;lt;Main user={user} /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

function Header({ user }) {
  return &amp;lt;UserMenu user={user} /&amp;gt;;
}

function Main({ user }) {
  return &amp;lt;Sidebar user={user} /&amp;gt;;
}

function Sidebar({ user }) {
  return &amp;lt;UserProfile user={user} /&amp;gt;;
}

function UserProfile({ user }) {
  return &amp;lt;p&amp;gt;Olá, {user.name}!&amp;lt;/p&amp;gt;;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este exemplo simples parece inofensivo, mas à medida que a aplicação cresce e mais componentes precisam dessas informações, o código pode rapidamente se tornar confuso e difícil de gerenciar. Qualquer alteração na estrutura da hierarquia pode exigir grandes mudanças no código, aumentando a probabilidade de erros.&lt;/p&gt;

&lt;h2&gt;
  
  
  Minha Experiência com Prop Drilling
&lt;/h2&gt;

&lt;p&gt;Enquanto trabalhava no desenvolvimento de um backoffice construído com Next.js, comecei enfrentando o problema clássico do prop drilling. No início, a aplicação era relativamente simples, e as informações globais eram gerenciadas eficientemente com o React Context ou passando props entre os componentes.&lt;/p&gt;

&lt;p&gt;No entanto, conforme a aplicação cresceu e se tornou mais complexa, alguns componentes precisavam compartilhar informações críticas com outros componentes que estavam distantes na hierarquia. Por exemplo, um componente que exibia uma lista precisava passar dados e funções para outro componente, que, por sua vez, deveria comunicar esses dados a subcomponentes ainda mais específicos. Isso exigiu que muitas propriedades fossem repassadas manualmente por vários níveis de componentes intermediários, mesmo que esses componentes não utilizassem as propriedades diretamente.&lt;/p&gt;

&lt;p&gt;Essa abordagem funcionava inicialmente, mas, com o tempo, tornou o código difícil de manter, aumentar ou refatorar. Cada alteração nos componentes superiores tinha um impacto em cascata, exigindo ajustes em diversos pontos do código. Além disso, entender o fluxo dos dados ficou cada vez mais complicado para novos membros da equipe.&lt;/p&gt;

&lt;p&gt;Foi nesse momento que percebi a necessidade de uma solução mais robusta para gerenciamento de estado. Bibliotecas como Redux, Zustand e Jotai começaram a fazer muito mais sentido, pois poderiam eliminar o excesso de dependências entre os componentes e centralizar o estado de forma mais clara e eficiente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Por que escolhi o Zustand?
&lt;/h2&gt;

&lt;p&gt;Com tantas opções disponíveis para gerenciamento de estado, como &lt;strong&gt;Redux&lt;/strong&gt;, &lt;strong&gt;MobX&lt;/strong&gt;, &lt;strong&gt;Jotai&lt;/strong&gt;, e até mesmo o próprio &lt;strong&gt;React Context&lt;/strong&gt;, decidi optar pelo &lt;strong&gt;Zustand&lt;/strong&gt;. Minha escolha foi baseada em alguns fatores importantes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Simplicidade&lt;/strong&gt;: O Zustand é extremamente simples de usar. Ele possui uma API enxuta e fácil de entender, o que torna a curva de aprendizado muito menor quando comparado a outras soluções mais robustas, como o Redux.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Leveza&lt;/strong&gt;: É uma biblioteca leve e sem dependências adicionais, o que contribui para um bundle size menor, mantendo a aplicação performática.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Escalabilidade&lt;/strong&gt;: Embora minha aplicação ainda seja de porte médio, escolhi o Zustand pensando no futuro. Ele me oferece a flexibilidade para escalar e organizar o estado de forma modular, sem adicionar complexidade desnecessária.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Menos Boilerplate&lt;/strong&gt;: Diferente de outras bibliotecas, o Zustand não exige a criação de actions ou reducers. Com apenas alguns hooks e configurações simples, já consigo gerenciar o estado global da aplicação de maneira eficiente.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Alternativa ao Context&lt;/strong&gt;: O React Context é uma excelente solução para casos simples, mas pode se tornar problemático em aplicações maiores devido ao problema de &lt;strong&gt;re-renders&lt;/strong&gt; desnecessários. O Zustand lida melhor com esses cenários, atualizando apenas os componentes que realmente dependem do estado alterado.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A partir do momento em que implementei o Zustand, percebi uma grande melhoria na organização e manutenção do meu código. A lógica de estado ficou centralizada e acessível, sem impactar negativamente a performance ou aumentar a complexidade da aplicação.&lt;/p&gt;

&lt;h2&gt;
  
  
  Usando Zustand para Resolver o Prop Drilling
&lt;/h2&gt;

&lt;p&gt;Com Zustand, podemos centralizar o estado e acessá-lo diretamente nos componentes que precisam das informações. Aqui está como o exemplo ficaria:&lt;br&gt;
&lt;strong&gt;Criando o Store com Zustand&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import create from 'zustand';

// Criamos um store centralizado para gerenciar o estado do usuário
const useUserStore = create((set) =&amp;gt; ({
  user: { name: "Gabriel" }, // Estado inicial
  setUser: (newUser) =&amp;gt; set({ user: newUser }), // Método para atualizar o estado
}));

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Refatorando os Componentes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Agora, em vez de passar o estado como prop por toda a hierarquia, podemos acessar o estado diretamente no componente que precisa dele.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function App() {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;Header /&amp;gt;
      &amp;lt;Main /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

function Header() {
  return &amp;lt;UserMenu /&amp;gt;;
}

function Main() {
  return &amp;lt;Sidebar /&amp;gt;;
}

function Sidebar() {
  return &amp;lt;UserProfile /&amp;gt;;
}

function UserProfile() {
  const user = useUserStore((state) =&amp;gt; state.user); // Acessamos o estado diretamente
  return &amp;lt;p&amp;gt;Olá, {user.name}!&amp;lt;/p&amp;gt;;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Como Isso Resolve o Prop Drilling?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Estado Centralizado: O estado do usuário está centralizado no store do Zustand.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Acesso Direto: Cada componente que precisa do estado pode acessá-lo diretamente, sem depender de componentes intermediários.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Escalabilidade: Se o estado ou lógica de atualização crescer, podemos gerenciá-lo no store de maneira modular.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Claro! Aqui está uma sugestão para a conclusão do seu artigo:&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Escolher o momento certo para introduzir uma biblioteca de gerenciamento de estado em uma aplicação React é uma decisão que depende muito do contexto e das necessidades do projeto. No meu caso, começar com soluções simples, como o React Context, funcionou bem em um primeiro momento. Contudo, à medida que a aplicação cresceu e os problemas de prop drilling começaram a aparecer, optei por adotar o &lt;strong&gt;Zustand&lt;/strong&gt; pela sua simplicidade, leveza e escalabilidade.&lt;/p&gt;

&lt;p&gt;Cada projeto tem seus próprios desafios, e não existe uma solução única que atenda a todos os casos. Por isso, é importante avaliar cuidadosamente os problemas que você está enfrentando e escolher a ferramenta que melhor se adapta ao cenário atual e ao crescimento futuro da aplicação.&lt;/p&gt;

&lt;p&gt;Se você está começando ou lidando com um projeto de porte pequeno, pode ser que o React Context seja suficiente. Mas, se a sua aplicação começa a demandar um gerenciamento de estado mais robusto, bibliotecas como &lt;strong&gt;Zustand&lt;/strong&gt;, &lt;strong&gt;Redux&lt;/strong&gt;, ou &lt;strong&gt;Jotai&lt;/strong&gt; podem ser uma excelente escolha.&lt;/p&gt;

&lt;p&gt;E você? Já enfrentou problemas com prop drilling ou precisou adotar uma solução de gerenciamento de estado? Compartilhe sua experiência nos comentários, adoraria saber como você lidou com isso!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Entendendo SOLID no Contexto do JavaScript: Conceitos e Exemplos</title>
      <dc:creator>Gabriel Teixeira da Silva</dc:creator>
      <pubDate>Mon, 16 Dec 2024 11:05:02 +0000</pubDate>
      <link>https://dev.to/gabrielteixeira44/entendendo-solid-no-contexto-do-javascript-conceitos-e-exemplos-4n9i</link>
      <guid>https://dev.to/gabrielteixeira44/entendendo-solid-no-contexto-do-javascript-conceitos-e-exemplos-4n9i</guid>
      <description>&lt;p&gt;A introdução do paradigma de Programação Orientada a Objetos (POO) popularizou conceitos fundamentais da programação, como Herança, Polimorfismo, Abstração e Encapsulamento. Rapidamente, a POO se tornou um paradigma amplamente aceito, com implementações em diversas linguagens como Java, C++, C#, JavaScript, entre outras. Contudo, à medida que os sistemas orientados a objetos se tornaram mais complexos, muitos projetos enfrentaram desafios de manutenção e adaptação a mudanças.&lt;/p&gt;

&lt;p&gt;Para melhorar a extensibilidade do software e reduzir a rigidez do código, Robert C. Martin (conhecido como Uncle Bob) apresentou, no início dos anos 2000, os princípios SOLID. &lt;/p&gt;

&lt;p&gt;SOLID é um acrônimo que reúne cinco princípios — Princípio da Responsabilidade Única, Princípio do Aberto/Fechado, Princípio da Substituição de Liskov, Princípio da Segregação de Interfaces e Princípio da Inversão de Dependências. Esses princípios ajudam desenvolvedores a projetar e escrever códigos mais manuteníveis, escaláveis e flexíveis. O objetivo? Elevar a qualidade do software criado com base no paradigma de Programação Orientada a Objetos.&lt;/p&gt;

&lt;p&gt;Neste artigo, exploraremos cada um dos princípios SOLID e mostraremos como aplicá-los no contexto de uma das linguagens mais populares da web: o JavaScript (apesar de o JavaScript implementar POO de uma maneira diferente, algo que exploraremos em outro artigo).&lt;/p&gt;

&lt;h2&gt;
  
  
  Princípio da Responsabilidade Única (SRP)
&lt;/h2&gt;

&lt;p&gt;O Princípio da Responsabilidade Única é representado pela primeira letra de SOLID. Esse princípio sugere que uma classe ou módulo deve ter apenas uma responsabilidade, ou seja, apenas uma razão para ser modificada.&lt;/p&gt;

&lt;p&gt;Simplificando, uma classe ou função deve desempenhar apenas um papel. Se uma classe lida com mais de uma funcionalidade, atualizar uma delas sem impactar as outras se torna complicado. Isso pode levar a falhas no desempenho do software ou até mesmo a bugs inesperados. Para evitar esses problemas, é importante escrever um código modular, onde as preocupações sejam separadas.&lt;/p&gt;

&lt;p&gt;Se uma classe ou função tiver muitas responsabilidades, ela se torna difícil de modificar, testar e manter. Ao aplicar o SRP, conseguimos criar sistemas mais organizados, com menos chances de erros. Vamos ver um exemplo prático em JavaScript:&lt;/p&gt;

&lt;h3&gt;
  
  
  Exemplo de SRP no JavaScript
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Código que viola o SRP&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Aqui temos uma classe que lida com várias responsabilidades ao mesmo tempo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Person {
  constructor(name, email) {
    this.name = name;
    this.email = email;
  }

  saveToDatabase() {
    console.log(`Salvando ${this.name} no banco de dados...`);
    // Lógica para salvar no banco de dados
  }

  sendWelcomeEmail() {
    console.log(`Enviando e-mail de boas-vindas para ${this.email}...`);
    // Lógica para enviar e-mail
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Problema:&lt;/p&gt;

&lt;p&gt;A classe Person está lidando tanto com o armazenamento de dados no banco quanto com o envio de e-mails, o que são responsabilidades diferentes. Se algo mudar na lógica de e-mails, a classe Person precisará ser alterada, o que pode causar problemas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Código que aplica o SRP:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Vamos separar as responsabilidades em classes diferentes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Person {
  constructor(name, email) {
    this.name = name;
    this.email = email;
  }
}

class PersonRepository {
  save(person) {
    console.log(`Salvando ${person.name} no banco de dados...`);
    // Lógica para salvar no banco de dados
  }
}

class EmailService {
  sendWelcomeEmail(person) {
    console.log(`Enviando e-mail de boas-vindas para ${person.email}...`);
    // Lógica para enviar e-mail
  }
}

// Uso:
const person = new Person("Gabriel", "gabriel@example.com");
const repository = new PersonRepository();
const emailService = new EmailService();

repository.save(person);
emailService.sendWelcomeEmail(person);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Por que é melhor?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Person&lt;/strong&gt; é responsável apenas por representar uma pessoa.&lt;br&gt;
&lt;strong&gt;PersonRepository&lt;/strong&gt; lida exclusivamente com o armazenamento de dados no banco.&lt;br&gt;
&lt;strong&gt;EmailService&lt;/strong&gt; cuida apenas do envio de e-mails.&lt;br&gt;
Essa separação de responsabilidades torna o código mais modular, fácil de testar e menos propenso a erros, além de simplificar futuras alterações.&lt;/p&gt;
&lt;h2&gt;
  
  
  Princípio Aberto/Fechado (OCP)
&lt;/h2&gt;

&lt;p&gt;O Princípio Aberto/Fechado afirma que os componentes de software (classes, funções, módulos, etc.) devem estar abertos para extensão, mas fechados para modificação. Em um primeiro momento, isso pode parecer contraditório, mas o princípio sugere que o código deve ser projetado de forma a permitir extensões sem que o código existente precise ser alterado.&lt;/p&gt;

&lt;p&gt;Esse princípio é essencial para a manutenção de bases de código grandes, pois permite a adição de novas funcionalidades com baixo risco de introduzir bugs. Em vez de modificar classes ou módulos existentes quando surgem novos requisitos, você deve estender as classes relevantes adicionando novos componentes.&lt;/p&gt;

&lt;p&gt;No JavaScript, o OCP pode ser implementado utilizando recursos como herança (ES6+) ou composição. Vamos explorar isso com um exemplo:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo sem aplicar o OCP (violação do princípio)&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Neste exemplo, temos uma classe Shape que calcula a área de diferentes formas geométricas. Para cada nova forma, precisamos modificar a classe principal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Shape {
  constructor(type, dimensions) {
    this.type = type;
    this.dimensions = dimensions;
  }

  calculateArea() {
    if (this.type === "circle") {
      return Math.PI * this.dimensions.radius ** 2;
    } else if (this.type === "rectangle") {
      return this.dimensions.width * this.dimensions.height;
    }
    // E assim por diante...
  }
}

const circle = new Shape("circle", { radius: 5 });
console.log(circle.calculateArea()); // Área do círculo

const rectangle = new Shape("rectangle", { width: 10, height: 20 });
console.log(rectangle.calculateArea()); // Área do retângulo

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Problema&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Sempre que uma nova forma for adicionada (como triângulo ou quadrado), precisamos modificar a classe Shape, o que viola o OCP.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo aplicando o OCP&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Vamos reestruturar o código para seguir o Princípio Aberto/Fechado usando classes e herança:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Classe base
class Shape {
  calculateArea() {
    throw new Error("Este método deve ser implementado pelas subclasses.");
  }
}

// Subclasses
class Circle extends Shape {
  constructor(radius) {
    super();
    this.radius = radius;
  }

  calculateArea() {
    return Math.PI * this.radius ** 2;
  }
}

class Rectangle extends Shape {
  constructor(width, height) {
    super();
    this.width = width;
    this.height = height;
  }

  calculateArea() {
    return this.width * this.height;
  }
}

// Uso:
const circle = new Circle(5);
console.log(circle.calculateArea()); // Saída: 78.54

const rectangle = new Rectangle(10, 20);
console.log(rectangle.calculateArea()); // Saída: 200

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Por que isso segue o OCP?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A classe base Shape está fechada para modificações, ou seja, não precisamos alterá-la para adicionar novas formas.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Para suportar uma nova forma, como um triângulo, basta criar uma nova subclasse que implemente o método calculateArea.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Princípio da Substituição de Liskov (LSP)
&lt;/h2&gt;

&lt;p&gt;O Princípio da Substituição de Liskov afirma que uma classe derivada deve ser substituível pela sua classe base sem que o funcionamento do sistema seja comprometido. Em outras palavras, se um objeto de uma classe base pode ser usado, um objeto de uma subclasse dessa classe também deve poder ser usado no lugar sem causar problemas.&lt;/p&gt;

&lt;p&gt;Este princípio é essencial para garantir que o código seja flexível e extensível sem introduzir comportamentos inesperados. Ele exige que as subclasses respeitem o contrato da classe base, garantindo que o comportamento esperado permaneça consistente. Na prática, isso significa que:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Subclasses devem sobrescrever os métodos da classe pai sem quebrar o código. Ou seja, as implementações das subclasses devem manter a consistência do comportamento esperado.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Subclasses não devem desviar do comportamento da classe pai. Subclasses podem adicionar funcionalidades, mas não devem alterar ou remover funcionalidades definidas na classe pai.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;O código que funciona com instâncias da classe pai deve funcionar também com instâncias das subclasses, sem precisar saber que a classe mudou. Isso significa que o código deve ser agnóstico em relação à classe específica utilizada, respeitando o contrato estabelecido pela classe base.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Violação do LSP&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Vamos começar com um exemplo onde o princípio é violado. Considere uma hierarquia de classes relacionada a retângulos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Rectangle {
  constructor(width, height) {
    this.width = width;
    this.height = height;
  }

  getArea() {
    return this.width * this.height;
  }
}

class Square extends Rectangle {
  constructor(side) {
    super(side, side);
  }

  set width(value) {
    this._width = value;
    this._height = value;
  }

  set height(value) {
    this._width = value;
    this._height = value;
  }

  get width() {
    return this._width;
  }

  get height() {
    return this._height;
  }
}

// Uso:
const rectangle = new Rectangle(10, 20);
console.log(rectangle.getArea()); // Saída: 200

const square = new Square(10);
square.width = 15;
console.log(square.getArea()); // Saída esperada: 225, mas pode causar confusão

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Problema:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Embora Square seja uma subclasse de Rectangle, o comportamento de Square é inconsistente. Quando alteramos width ou height em Square, isso afeta ambas as dimensões, o que não é o caso para Rectangle.&lt;/li&gt;
&lt;li&gt;Isso quebra o contrato implícito da classe base, violando o LSP.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Como corrigir o LSP&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Para evitar essa violação, podemos separar Square e Rectangle em duas classes independentes que implementam uma interface comum (ou seguem um contrato comum no JavaScript):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Shape {
  getArea() {
    throw new Error("Este método deve ser implementado pela subclasse.");
  }
}

class Rectangle extends Shape {
  constructor(width, height) {
    super();
    this.width = width;
    this.height = height;
  }

  getArea() {
    return this.width * this.height;
  }
}

class Square extends Shape {
  constructor(side) {
    super();
    this.side = side;
  }

  getArea() {
    return this.side ** 2;
  }
}

// Uso:
const rectangle = new Rectangle(10, 20);
console.log(rectangle.getArea()); // Saída: 200

const square = new Square(10);
console.log(square.getArea()); // Saída: 100

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Por que isso segue o LSP?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rectangle e Square agora são classes independentes, ambas respeitando o contrato da classe base Shape.&lt;/li&gt;
&lt;li&gt;O comportamento de cada classe é consistente com sua definição, sem causar problemas quando substituídas.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Princípio da Segregação de Interfaces (ISP)
&lt;/h3&gt;

&lt;p&gt;O &lt;strong&gt;Princípio da Segregação de Interfaces (ISP)&lt;/strong&gt; estabelece que &lt;strong&gt;nenhum cliente deve ser forçado a depender de métodos ou interfaces que não utiliza&lt;/strong&gt;. Em termos práticos, isso significa que devemos criar interfaces menores e mais específicas, relevantes para os clientes que as consomem, ao invés de interfaces grandes e monolíticas que forçam os clientes a implementar métodos desnecessários.&lt;/p&gt;

&lt;p&gt;Manter nossas interfaces compactas oferece diversas vantagens:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Facilita a &lt;strong&gt;manutenção&lt;/strong&gt;, &lt;strong&gt;depuração&lt;/strong&gt; e &lt;strong&gt;testes&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Evita dependências desnecessárias entre diferentes partes do sistema.&lt;/li&gt;
&lt;li&gt;Minimiza o impacto de mudanças: alterações em uma parte da interface não devem forçar alterações em outras partes do código.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sem o ISP, mudanças em interfaces grandes podem exigir refatorações extensas e complexas, especialmente em bases de código maiores.&lt;/p&gt;

&lt;h3&gt;
  
  
  Desafio no JavaScript
&lt;/h3&gt;

&lt;p&gt;Diferentemente de linguagens baseadas em C, como Java ou C#, o JavaScript &lt;strong&gt;não possui suporte nativo a interfaces&lt;/strong&gt;. Entretanto, podemos aplicar os conceitos de ISP utilizando objetos, classes e contratos implícitos. &lt;/p&gt;

&lt;h3&gt;
  
  
  Exemplo sem aplicar o ISP (violação do princípio)
&lt;/h3&gt;

&lt;p&gt;Aqui temos uma interface implícita que força diferentes classes a implementar métodos que nem sempre fazem sentido:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MultiFunctionPrinter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;printDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Imprimindo: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;scanDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Escaneando: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;faxDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Enviando fax: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Impressora básica que não precisa de fax&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BasicPrinter&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;MultiFunctionPrinter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;faxDocument&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Fax não suportado nesta impressora.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Uso:&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;printer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BasicPrinter&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;printer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;printDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Relatório&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;printer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;faxDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Relatório&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Erro!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Problema:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A classe &lt;code&gt;BasicPrinter&lt;/code&gt; é forçada a implementar um método &lt;code&gt;faxDocument&lt;/code&gt;, mesmo que não seja necessário.&lt;/li&gt;
&lt;li&gt;Isso viola o ISP porque &lt;code&gt;BasicPrinter&lt;/code&gt; está dependente de uma funcionalidade que não utiliza.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Corrigindo para aplicar o ISP
&lt;/h3&gt;

&lt;p&gt;Podemos dividir a interface em partes menores, cada uma representando um conjunto de responsabilidades específicas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Interfaces menores representadas por classes ou funções&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Printer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;printDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Imprimindo: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Scanner&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;scanDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Escaneando: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Fax&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;faxDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Enviando fax: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Classes específicas implementam apenas as interfaces necessárias&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BasicPrinter&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Printer&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AdvancedPrinter&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Printer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scanner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Scanner&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Fax&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;scanDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scanner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;scanDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;faxDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fax&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;faxDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Uso:&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;basicPrinter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BasicPrinter&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;basicPrinter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;printDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Relatório&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Saída: Imprimindo: Relatório&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;advancedPrinter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AdvancedPrinter&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;advancedPrinter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;printDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Contrato&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Saída: Imprimindo: Contrato&lt;/span&gt;
&lt;span class="nx"&gt;advancedPrinter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;scanDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Contrato&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Saída: Escaneando: Contrato&lt;/span&gt;
&lt;span class="nx"&gt;advancedPrinter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;faxDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Contrato&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Saída: Enviando fax: Contrato&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Por que agora segue o ISP?&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Cada classe (ou "interface") está focada em uma responsabilidade específica (&lt;code&gt;Printer&lt;/code&gt;, &lt;code&gt;Scanner&lt;/code&gt;, &lt;code&gt;Fax&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Classes concretas, como &lt;code&gt;BasicPrinter&lt;/code&gt; e &lt;code&gt;AdvancedPrinter&lt;/code&gt;, implementam apenas as funcionalidades que realmente utilizam.&lt;/li&gt;
&lt;li&gt;O sistema agora é mais modular, fácil de estender e menos propenso a erros ao adicionar novas funcionalidades.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Benefícios do ISP&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Modularidade:&lt;/strong&gt; As interfaces menores tornam o código mais fácil de entender e gerenciar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redução de dependências:&lt;/strong&gt; Classes e módulos dependem apenas das funcionalidades relevantes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extensibilidade:&lt;/strong&gt; Novas funcionalidades podem ser adicionadas sem impactar partes não relacionadas do sistema.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Aqui está uma versão adaptada para português da explicação do &lt;strong&gt;Princípio da Inversão de Dependência (Dependency Inversion Principle - DIP)&lt;/strong&gt; com exemplos em JavaScript:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Princípio da Inversão de Dependência (DIP)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;O &lt;strong&gt;Princípio da Inversão de Dependência (DIP)&lt;/strong&gt; estabelece que &lt;strong&gt;módulos de alto nível (como lógica de negócios) devem depender de abstrações, e não de implementações concretas&lt;/strong&gt;. Isso significa que, em vez de classes de alto nível se conectarem diretamente a classes de baixo nível, ambas devem depender de uma abstração comum.&lt;/p&gt;

&lt;p&gt;Esse princípio ajuda a reduzir as dependências diretas no código, tornando-o mais modular, flexível e testável. Ele permite que desenvolvedores modifiquem e expandam a lógica de alto nível sem complicações, mesmo que os componentes de baixo nível mudem.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Por que o DIP favorece abstrações?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Ao introduzir abstrações, podemos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Reduzir impactos de mudanças:&lt;/strong&gt; Alterar uma implementação concreta não afeta a lógica de alto nível.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Melhorar a testabilidade:&lt;/strong&gt; Podemos usar mocks ou stubs para simular abstrações durante os testes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aumentar a flexibilidade:&lt;/strong&gt; O sistema se torna mais modular e fácil de estender.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;O DIP promove o &lt;strong&gt;acoplamento fraco (loose coupling)&lt;/strong&gt; em vez do &lt;strong&gt;acoplamento forte (tight coupling)&lt;/strong&gt;. Isso significa que as partes do sistema são menos dependentes umas das outras, facilitando a manutenção e expansão.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Exemplo sem aplicar o DIP (violação do princípio)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Neste exemplo, uma classe de alto nível (&lt;code&gt;OrderService&lt;/code&gt;) depende diretamente de uma classe de baixo nível (&lt;code&gt;EmailService&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EmailService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;sendEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Enviando e-mail: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;emailService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;EmailService&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;placeOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Pedido realizado:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;emailService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Seu pedido foi recebido.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Uso:&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;orderService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;OrderService&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;orderService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;placeOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Pedido #123&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Problema:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A classe &lt;code&gt;OrderService&lt;/code&gt; está fortemente acoplada à implementação de &lt;code&gt;EmailService&lt;/code&gt;. Se quisermos trocar &lt;code&gt;EmailService&lt;/code&gt; por outro serviço (como &lt;code&gt;SMSService&lt;/code&gt;), teremos que modificar &lt;code&gt;OrderService&lt;/code&gt;, violando o DIP.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Exemplo aplicando o DIP&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Agora vamos introduzir uma abstração para desacoplar &lt;code&gt;OrderService&lt;/code&gt; da implementação concreta de &lt;code&gt;EmailService&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Abstração&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NotificationService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;sendNotification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Este método deve ser implementado por subclasses.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Implementação concreta&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EmailService&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;NotificationService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;sendNotification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Enviando e-mail: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SMSService&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;NotificationService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;sendNotification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Enviando SMS: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Classe de alto nível&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;notificationService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;notificationService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;notificationService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Injeção de dependência&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;placeOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Pedido realizado:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;notificationService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendNotification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Seu pedido foi recebido.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Uso:&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;emailService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;EmailService&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;smsService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SMSService&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;orderServiceWithEmail&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;OrderService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;emailService&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;orderServiceWithEmail&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;placeOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Pedido #123&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Saída: Enviando e-mail: Seu pedido foi recebido.&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;orderServiceWithSMS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;OrderService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;smsService&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;orderServiceWithSMS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;placeOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Pedido #124&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Saída: Enviando SMS: Seu pedido foi recebido.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Por que agora segue o DIP?&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Desacoplamento:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;OrderService&lt;/code&gt; depende da abstração &lt;code&gt;NotificationService&lt;/code&gt;, e não de implementações concretas como &lt;code&gt;EmailService&lt;/code&gt; ou &lt;code&gt;SMSService&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Podemos alterar ou substituir a implementação concreta sem modificar &lt;code&gt;OrderService&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Injeção de dependência:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O &lt;code&gt;OrderService&lt;/code&gt; recebe a dependência (&lt;code&gt;notificationService&lt;/code&gt;) como parâmetro no construtor. Isso é conhecido como &lt;strong&gt;injeção de dependência (dependency injection)&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Flexibilidade:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Podemos adicionar novas implementações de &lt;code&gt;NotificationService&lt;/code&gt; (como &lt;code&gt;PushNotificationService&lt;/code&gt;) sem alterar a lógica de alto nível em &lt;code&gt;OrderService&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Vantagens do DIP&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Facilidade de manutenção:&lt;/strong&gt; Alterar componentes de baixo nível não afeta módulos de alto nível.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modularidade:&lt;/strong&gt; As partes do sistema são mais independentes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testabilidade:&lt;/strong&gt; É fácil criar mocks para testar módulos de alto nível sem depender de implementações reais.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extensibilidade:&lt;/strong&gt; Novas funcionalidades podem ser adicionadas sem causar grandes alterações no sistema.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Conclusão
&lt;/h3&gt;

&lt;p&gt;Os princípios SOLID são fundamentais para criar sistemas mais organizados, flexíveis e fáceis de manter. Aplicá-los no contexto do JavaScript pode parecer desafiador inicialmente, especialmente por ser uma linguagem dinâmica e sem suporte nativo a alguns conceitos como interfaces. No entanto, como vimos, com abordagens práticas como herança, abstrações e injeção de dependências, é possível incorporar esses princípios e alcançar um código mais modular e resiliente. &lt;/p&gt;

&lt;p&gt;Ao adotar SOLID no dia a dia, você não apenas melhora a qualidade do seu código, mas também reduz o risco de bugs e torna o desenvolvimento mais eficiente a longo prazo. Que tal começar a aplicar esses conceitos no seu próximo projeto?&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Melhores Práticas de Acessibilidade Web com ARIA (Accessible Rich Internet Applications)</title>
      <dc:creator>Gabriel Teixeira da Silva</dc:creator>
      <pubDate>Fri, 20 Sep 2024 14:02:37 +0000</pubDate>
      <link>https://dev.to/gabrielteixeira44/melhores-praticas-de-acessibilidade-web-com-aria-accessible-rich-internet-applications-3gdn</link>
      <guid>https://dev.to/gabrielteixeira44/melhores-praticas-de-acessibilidade-web-com-aria-accessible-rich-internet-applications-3gdn</guid>
      <description>&lt;p&gt;A acessibilidade web é uma parte essencial do desenvolvimento de interfaces, especialmente quando falamos de componentes dinâmicos e interativos que precisam ser usados por todas as pessoas, independentemente de suas habilidades. Nesse contexto, a WAI-ARIA (Accessible Rich Internet Applications) oferece um conjunto de atributos que tornam esses componentes mais acessíveis para usuários de tecnologias assistivas, como leitores de tela.&lt;/p&gt;

&lt;p&gt;Neste artigo, vamos explorar o que é WAI-ARIA, como usá-lo corretamente e compartilhar exemplos práticos de sua implementação.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é WAI-ARIA?
&lt;/h2&gt;

&lt;p&gt;WAI-ARIA, ou Accessible Rich Internet Applications, é um conjunto de especificações desenvolvido pelo W3C que define como tornar o conteúdo e os componentes de interfaces mais acessíveis para usuários com deficiências.&lt;/p&gt;

&lt;p&gt;Esses atributos são especialmente úteis em componentes interativos complexos, como menus dinâmicos, modais e sliders, onde a semântica padrão do HTML não é suficiente para comunicar a natureza interativa desses elementos para tecnologias assistivas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Principais Atributos ARIA
&lt;/h2&gt;

&lt;p&gt;Aqui estão alguns dos atributos ARIA mais comuns e como eles podem ser usados para melhorar a acessibilidade de componentes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. aria-label&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O atributo aria-label fornece uma descrição personalizada para um elemento interativo. Ele é útil quando o conteúdo visual do elemento não é suficiente para descrevê-lo adequadamente para leitores de tela.&lt;/p&gt;

&lt;p&gt;Exemplo de Uso:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;button aria-label="Fechar janela"&amp;gt;X&amp;lt;/button&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Por que usar: Em casos onde o texto visível não é suficiente para descrever a função do botão (como um ícone), o aria-label adiciona um texto descritivo que será lido por leitores de tela.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. aria-hidden&lt;/strong&gt;&lt;br&gt;
O atributo aria-hidden indica que um elemento, e todos os seus filhos, devem ser ignorados por tecnologias assistivas, como leitores de tela.&lt;/p&gt;

&lt;p&gt;Exemplo de Uso:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div aria-hidden="true"&amp;gt;Este conteúdo será ignorado pelo leitor de tela&amp;lt;/div&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Por que usar: É útil quando há elementos decorativos ou repetidos no layout que não devem ser anunciados pelos leitores de tela. Também pode ser aplicado para ocultar elementos temporariamente&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. aria-live&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O aria-live é um atributo que define a prioridade com que uma mudança no conteúdo de uma área deve ser anunciada por um leitor de tela.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Valores possíveis: off, polite, e assertive.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Exemplo de Uso:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;div aria-live="polite"&amp;gt;Notificações serão lidas quando o usuário estiver pronto.&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Por que usar: Ele é útil em áreas onde o conteúdo muda dinamicamente (como uma notificação ou mensagem de erro), e é necessário garantir que essas mudanças sejam anunciadas ao usuário.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. aria-expanded&lt;/strong&gt;&lt;br&gt;
O aria-expanded é usado para indicar o estado expandido ou colapsado de um elemento interativo, como um menu dropdown ou um acordeão.&lt;/p&gt;

&lt;p&gt;Exemplo de Uso:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;button aria-expanded="false" aria-controls="menu"&amp;gt;Abrir Menu&amp;lt;/button&amp;gt;
&amp;lt;div id="menu" hidden&amp;gt;
    &amp;lt;p&amp;gt;Conteúdo do menu...&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Por que usar: Ele é importante para indicar o estado de visibilidade de um elemento e garantir que usuários de leitores de tela saibam se algo foi expandido ou colapsado.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5. aria-controls&lt;/strong&gt;&lt;br&gt;
O atributo aria-controls é utilizado para indicar que o elemento atual controla a visibilidade ou o conteúdo de outro elemento. Ele é particularmente útil em componentes interativos, como menus, acordeões, ou dropdowns, onde o estado de um elemento (como um botão) afeta a exibição de outro (como um painel ou uma lista).&lt;br&gt;
Como Funciona&lt;/p&gt;

&lt;p&gt;O aria-controls recebe o id do elemento que está sendo controlado. Esse atributo ajuda tecnologias assistivas, como leitores de tela, a entender que um determinado elemento tem controle sobre outro, melhorando a acessibilidade e a experiência do usuário.&lt;/p&gt;

&lt;p&gt;Exemplo de Uso:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;button aria-expanded="false" aria-controls="menu"&amp;gt;Abrir Menu&amp;lt;/button&amp;gt;
&amp;lt;div id="menu" hidden&amp;gt;
    &amp;lt;p&amp;gt;Conteúdo do menu...&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste exemplo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;O botão tem o atributo aria-controls="menu", indicando que ele controla a exibição do elemento com o id="menu".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Quando o usuário interagir com o botão e o menu for exibido ou oculto, o atributo aria-expanded pode ser atualizado para refletir o estado atual, informando ao leitor de tela se o menu está aberto (true) ou fechado (false).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;A acessibilidade é um aspecto fundamental no desenvolvimento web, e o uso correto de atributos ARIA pode transformar a experiência de usuários que dependem de tecnologias assistivas, como leitores de tela. Atributos como aria-label, aria-hidden, aria-live, aria-expanded e aria-controls ajudam a garantir que componentes dinâmicos e interativos sejam compreendidos e acessíveis a todos os usuários.&lt;/p&gt;

&lt;p&gt;Ao implementar esses atributos nos seus projetos, você estará contribuindo para a criação de uma web mais inclusiva, onde todos possam navegar e interagir com conteúdo sem barreiras.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quer aprender mais?
&lt;/h2&gt;

&lt;p&gt;Os atributos ARIA são amplos e oferecem muitas opções para tornar interfaces mais acessíveis. Se você quiser se aprofundar no uso de ARIA e conhecer outros atributos que podem melhorar a acessibilidade do seu site, recomendo conferir a &lt;a href="https://www.w3.org/TR/wai-aria-1.2/" rel="noopener noreferrer"&gt;documentação completa de WAI-ARIA&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Além disso, seguir as diretrizes da &lt;a href="https://www.w3.org/TR/WCAG22/" rel="noopener noreferrer"&gt;WCAG (Web Content Accessibility Guidelines)&lt;/a&gt;  pode ajudar a garantir que seu site atenda aos padrões internacionais de acessibilidade&lt;/p&gt;

&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;p&gt;Para se aprofundar ainda mais sobre acessibilidade web e garantir que seus projetos sigam as melhores práticas, consulte os seguintes recursos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.w3.org/TR/WCAG22/" rel="noopener noreferrer"&gt;WCAG 2.2 - Diretrizes de Acessibilidade para o Conteúdo Web (em inglês)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.w3.org/WAI/WCAG22/quickref/?versions=2.1" rel="noopener noreferrer"&gt;Resumo Rápido das WCAG 2.2 (em inglês)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.w3c.br/traducoes/wcag/wcag22-pt-BR/" rel="noopener noreferrer"&gt;Tradução para o português das WCAG 2.2&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Esses links são excelentes pontos de partida para aprofundar seus conhecimentos sobre acessibilidade e aplicar diretrizes fundamentais em seus projetos web.&lt;/p&gt;

&lt;p&gt;Se precisar de ajuda ou tiver dúvidas, estou à disposição. Sinta-se à vontade para entrar em contato!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Desvendando o Async/Await: Simplificando a Programação Assíncrona com JavaScript</title>
      <dc:creator>Gabriel Teixeira da Silva</dc:creator>
      <pubDate>Thu, 04 Jul 2024 18:36:05 +0000</pubDate>
      <link>https://dev.to/gabrielteixeira44/desvendando-o-asyncawait-simplificando-a-programacao-assincrona-e0c</link>
      <guid>https://dev.to/gabrielteixeira44/desvendando-o-asyncawait-simplificando-a-programacao-assincrona-e0c</guid>
      <description>&lt;h2&gt;
  
  
  Conceitos Básicos
&lt;/h2&gt;

&lt;h3&gt;
  
  
  O que é Programação Assíncrona?
&lt;/h3&gt;

&lt;p&gt;Programação assíncrona é uma técnica de programação que permite a execução de operações que podem demorar um certo tempo para serem concluídas, como requisições de rede, leitura de arquivos ou consultas a bancos de dados, sem bloquear o fluxo principal do programa. Em vez de esperar que essas operações terminem, o programa pode continuar executando outras tarefas. Isso é especialmente útil em aplicações web, onde a responsividade e a performance são cruciais para a experiência do usuário.&lt;/p&gt;

&lt;h3&gt;
  
  
  Callbacks e Promises
&lt;/h3&gt;

&lt;p&gt;Antes do advento de async/await, a programação assíncrona em JavaScript era tradicionalmente feita usando callbacks e Promises.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Callbacks&lt;/strong&gt;: Um callback é uma função passada como argumento para outra função, que será executada após a conclusão de uma operação assíncrona. No entanto, callbacks podem levar ao que é conhecido como "callback hell", onde múltiplos callbacks aninhados tornam o código difícil de ler e manter.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Promises&lt;/strong&gt;: Promises foram introduzidas para melhorar a legibilidade do código assíncrono. Uma Promise representa um valor que pode estar disponível agora, no futuro ou nunca. Promises permitem encadear operações assíncronas de maneira mais clara e gerenciável.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  O que é Async/Await?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;async&lt;/code&gt; e &lt;code&gt;await&lt;/code&gt; são palavras-chave introduzidas no ES2017 (ES8) que simplificam ainda mais o uso de Promises, permitindo escrever código assíncrono que parece síncrono.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;async&lt;/strong&gt;: A palavra-chave &lt;code&gt;async&lt;/code&gt; é usada para declarar uma função assíncrona. Uma função assíncrona sempre retorna uma Promise.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;await&lt;/strong&gt;: A palavra-chave &lt;code&gt;await&lt;/code&gt; só pode ser usada dentro de uma função assíncrona. Ela pausa a execução da função até que a Promise seja resolvida, simplificando o fluxo do código.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.example.com/data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Com &lt;code&gt;async&lt;/code&gt; e &lt;code&gt;await&lt;/code&gt;, o código assíncrono se torna mais linear e fácil de entender, eliminando a necessidade de encadeamento excessivo de &lt;code&gt;then&lt;/code&gt; e &lt;code&gt;catch&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exemplos Práticos e Tratamento de Erros
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Exemplo Simples
&lt;/h3&gt;

&lt;p&gt;Vamos começar com um exemplo simples de uma função assíncrona que busca dados de uma API usando &lt;code&gt;async/await&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.example.com/data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Múltiplas Chamadas Assíncronas
&lt;/h3&gt;

&lt;p&gt;Às vezes, você precisa fazer múltiplas chamadas assíncronas e esperar que todas sejam concluídas. Você pode usar &lt;code&gt;Promise.all&lt;/code&gt; para isso.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchMultipleData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;response1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
        &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.example.com/data1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.example.com/data2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data2&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;fetchMultipleData&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;data1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data2&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Tratamento de Erros com Try/Catch
&lt;/h3&gt;

&lt;p&gt;O uso de &lt;code&gt;try/catch&lt;/code&gt; em funções assíncronas permite capturar e lidar com erros de forma clara e concisa.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.example.com/data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Network response was not ok&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Failed to fetch data:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exemplo Completo: Integração com API e Tratamento de Erros
&lt;/h3&gt;

&lt;p&gt;Vamos combinar tudo o que aprendemos em um exemplo mais completo. Suponha que estamos construindo uma função que busca e processa dados de múltiplas APIs e lida com possíveis erros.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchUserData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.example.com/user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;userResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Failed to fetch user data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;userResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;postsResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`https://api.example.com/users/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/posts`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;postsResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Failed to fetch user posts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userPosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;postsResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;userPosts&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error fetching data:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;fetchUserData&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User Data:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User Posts:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userPosts&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;async/await&lt;/code&gt; simplifica significativamente a programação assíncrona em JavaScript, tornando o código mais legível e fácil de manter. Com a capacidade de escrever código assíncrono que parece síncrono, desenvolvedores podem evitar os problemas comuns de callbacks aninhados e o encadeamento excessivo de Promises.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recursos Adicionais
&lt;/h2&gt;

&lt;p&gt;Para aprofundar seu conhecimento sobre &lt;code&gt;async/await&lt;/code&gt; e programação assíncrona, aqui estão alguns recursos úteis:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await"&gt;Documentação MDN sobre async/await&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise"&gt;Artigo sobre Promises no MDN&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=V_Kr9OSfDeU"&gt;Vídeo tutorial sobre async/await&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Acessibilidade em Foco: Novidades no GNOME 46</title>
      <dc:creator>Gabriel Teixeira da Silva</dc:creator>
      <pubDate>Sat, 23 Mar 2024 18:39:46 +0000</pubDate>
      <link>https://dev.to/gabrielteixeira44/acessibilidade-em-foco-novidades-no-gnome-46-d34</link>
      <guid>https://dev.to/gabrielteixeira44/acessibilidade-em-foco-novidades-no-gnome-46-d34</guid>
      <description>&lt;p&gt;Antes de mergulharmos nas inovadoras melhorias de acessibilidade introduzidas pelo GNOME na versão 46, talvez você esteja se perguntando: o que exatamente é o GNOME? Permita-me oferecer uma breve introdução a este influente ambiente de desktop.&lt;/p&gt;

&lt;h2&gt;
  
  
  o que exatamente é o GNOME?
&lt;/h2&gt;

&lt;p&gt;O GNOME é um ambiente de desktop livre e de código aberto, amplamente reconhecido por sua simplicidade, acessibilidade e elegância. Projetado para ser intuitivo e eficiente, é uma das interfaces gráficas mais populares entre os usuários de sistemas operacionais baseados em Linux e UNIX. Com um forte foco em usabilidade e experiência do usuário, o GNOME oferece uma área de trabalho organizada que facilita a navegação, o gerenciamento de janelas e a interação com aplicativos e arquivos. Além disso, é desenvolvido e mantido por uma comunidade ativa, que se dedica a melhorar continuamente suas funcionalidades e acessibilidade, garantindo que o ambiente seja inclusivo e acessível a todos os usuários.&lt;/p&gt;

&lt;p&gt;Caso tenha interesse em explorar mais sobre o universo do GNOME e suas vastas possibilidades, ao final deste artigo, você encontrará uma seleção de links cuidadosamente escolhidos. Eles servirão como um ponto de partida para aprofundar seus conhecimentos no fascinante mundo do GNOME.&lt;/p&gt;

&lt;h2&gt;
  
  
  Melhorias de Acessibilidade no Gnome 46
&lt;/h2&gt;

&lt;p&gt;A acessibilidade é um foco primordial no desenvolvimento do GNOME 46, com diversas melhorias significativas já implementadas e outras previstas para a versão 4.14 do GTK. Esses avanços abrangem vários aspectos da acessibilidade, refletindo o compromisso contínuo em tornar o GNOME ainda mais inclusivo. Um destaque especial neste esforço tem sido o aprimoramento do leitor de tela Orca, que recebeu atenção especial para melhorar a experiência do usuário e expandir suas funcionalidades.&lt;/p&gt;

&lt;p&gt;Você pode estar curioso sobre o que exatamente é o &lt;strong&gt;GTK&lt;/strong&gt;, mencionado anteriormente. Vamos esclarecer: &lt;strong&gt;GTK&lt;/strong&gt;, originalmente uma abreviação para GIMP Toolkit, é uma biblioteca de desenvolvimento fundamental para a criação de interfaces gráficas de usuário (GUIs) no ambiente GNOME. Facilitando o desenvolvimento de aplicativos visuais ricos e interativos, o GTK serve como a espinha dorsal para a maioria dos aplicativos dentro do ecossistema GNOME. Com uma arquitetura extensível e suporte a várias linguagens de programação, o GTK não apenas permite, mas encoraja o desenvolvimento de aplicativos acessíveis e visualmente atraentes.&lt;/p&gt;

&lt;p&gt;Retomando nosso foco nas inovações em acessibilidade que o GNOME 46 introduziu, vamos explorar as principais melhorias a seguir.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Por debaixo do capô, um significativo esforço de modernização está em andamento. Isso resultará em melhor desempenho e confiabilidade, além de possibilitar a compatibilidade com o Wayland e aplicativos em sandbox no futuro.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Uma nova funcionalidade de modo de suspensão foi adicionada. Esse recurso bastante solicitado permite aos usuários desativar temporariamente o Orca, usando o atalho &lt;code&gt;Ctrl&lt;/code&gt;+&lt;code&gt;Alt&lt;/code&gt;+&lt;code&gt;Shift&lt;/code&gt;+&lt;code&gt;Q&lt;/code&gt;. O modo de suspensão é útil ao usar máquinas virtuais que possuem seus próprios leitores de tela, bem como aplicativos autovocais.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Novos comandos permitem que o Orca informe o status do sistema, incluindo status da bateria, uso de CPU e memória.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A navegação por tabelas foi bastante melhorada, com mais aplicativos sendo suportados e novos comandos adicionados, incluindo navegação por tabela de alternância (&lt;code&gt;Orca&lt;/code&gt;+&lt;code&gt;Shift&lt;/code&gt;+&lt;code&gt;T&lt;/code&gt;) e mover para a célula final (&lt;code&gt;Orca&lt;/code&gt;+&lt;code&gt;Alt&lt;/code&gt;+&lt;code&gt;Shift&lt;/code&gt;+&lt;code&gt;🡰&lt;/code&gt;/&lt;code&gt;🡲&lt;/code&gt;/&lt;code&gt;🡱&lt;/code&gt;/&lt;code&gt;🡳&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;O Orca agora tem suporte experimental para Spiel, uma emocionante API de síntese de fala de próxima geração. Aqueles que estão interessados ​​nessa funcionalidade &lt;a href="https://gitlab.gnome.org/GNOME/orca#experimental-features"&gt;são convidados a ajudar a&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O Orca não foi o único lugar onde aconteceram melhorias de acessibilidade para o GNOME 46. Outras melhorias incluem um modo de alto contraste que agora está mais consistente e utilizável, e uma nova configuração para mostrar símbolos de ligado e desligado em interruptores.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;A acessibilidade no universo Linux raramente ocupa os holofotes, mas estou aqui para mudar essa narrativa. Pode ser uma surpresa para muitos descobrir que o Linux possui um leitor de tela nativo. Ainda há um caminho longo a percorrer em termos de acessibilidade no GNOME e no Linux, especialmente com a transição para o Wayland como protocolo padrão em várias distribuições. Contudo, é animador ver os progressos sendo feitos nesta área. Como um apaixonado pelo open source e um defensor da acessibilidade, decidi contribuir ativamente para melhorar a acessibilidade no Linux.&lt;/p&gt;

&lt;p&gt;Este é apenas o início de uma série dedicada a explorar acessibilidade e Linux. Se você tiver dúvidas, sugestões ou quiser iniciar uma conversa sobre este tema tão importante, não hesite em entrar em contato. Agradeço imensamente por ter acompanhado este post até o fim. Fique ligado para mais insights e discussões em futuros artigos. Até lá, que a força esteja com você em sua jornada pelo mundo do Linux e da acessibilidade.&lt;/p&gt;

&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.gnome.org/"&gt;Gnome&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://release.gnome.org/46/"&gt;Gnome Releases Notes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.gnome.org/"&gt;Gnome Development&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.gtk.org/"&gt;Blog GTK&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://snwh.pages.gitlab.gnome.org/orca.gnome.org/"&gt;Orca&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gitlab.gnome.org/GNOME/orca"&gt;Gitlab Orca&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Listas Lineares Descomplicadas: Entenda a Base das Estruturas de Dados</title>
      <dc:creator>Gabriel Teixeira da Silva</dc:creator>
      <pubDate>Wed, 21 Feb 2024 15:28:28 +0000</pubDate>
      <link>https://dev.to/gabrielteixeira44/listas-lineares-descomplicadas-entenda-a-base-das-estruturas-de-dados-fak</link>
      <guid>https://dev.to/gabrielteixeira44/listas-lineares-descomplicadas-entenda-a-base-das-estruturas-de-dados-fak</guid>
      <description>&lt;p&gt;Olá, pessoal! Estou de volta para mergulharmos juntos no universo das estruturas de dados, um pilar fundamental no mundo da computação. Recentemente, decidi revisitar e aprofundar meus conhecimentos nessa área crítica, e quero compartilhar essa jornada com vocês. Hoje, nosso foco será nas listas lineares: vamos explorar o que são, como funcionam, sua origem e por que são tão essenciais para a programação. Este artigo é apenas o início de uma série dedicada a desvendar as estruturas de dados, então, preparem-se para aprender e crescer conosco nessa aventura. Vamos lá?&lt;/p&gt;

&lt;h2&gt;
  
  
  Entendendo Listas Lineares com Alocação Sequencial
&lt;/h2&gt;

&lt;p&gt;No universo das estruturas de dados, a linearidade é definida pela capacidade de percorrer elementos de forma sequencial, um após o outro, estabelecendo um único caminho para essa travessia. Neste contexto, as listas se destacam como exemplares de estruturas lineares, compostas por uma série de elementos organizados em sequência. No entanto, essa sequencialidade, tão clara no nível do software, nem sempre se reflete diretamente no hardware. Isso significa que, embora elementos adjacentes (nas posições &lt;em&gt;i e i + 1&lt;/em&gt;) pareçam consecutivos na estrutura de dados, eles podem não estar fisicamente adjacentes na memória do computador.&lt;/p&gt;

&lt;p&gt;A alocação sequencial surge como uma solução para essa discrepância, garantindo que os elementos de uma lista sejam armazenados de forma contígua na memória. Esse método de armazenamento não apenas simplifica o acesso e a gestão dos elementos, mas também otimiza o desempenho da lista ao minimizar o tempo necessário para localizar cada elemento. Ao armazenar dados de forma sequencial, facilitamos a implementação de algoritmos eficientes para manipulação dessas listas, desde operações simples como inserção e remoção até tarefas mais complexas de busca e ordenação. A alocação sequencial, portanto, é fundamental para a eficácia e a eficiência das listas lineares em diversas aplicações computacionais, representando um elo crítico entre a teoria abstrata das estruturas de dados e a prática concreta de programação.&lt;/p&gt;

&lt;p&gt;Tomemos o JavaScript como um exemplo prático: as arrays, que são declaradas com colchetes [], exemplificam perfeitamente o conceito de listas lineares com alocação sequencial. Essa característica permite que realizemos acessos aleatórios aos seus elementos utilizando índices. Por exemplo, ao escrevermos lista[3], estamos acessando diretamente o quarto elemento da array (considerando que, em JavaScript, a contagem de índices inicia-se em 0). Esse acesso direto é possível porque a array armazena seus elementos de forma contígua na memória, facilitando a localização de qualquer item sem a necessidade de percorrer sequencialmente a lista desde o início. Este método de acesso otimiza significativamente a eficiência de operações de leitura e escrita em listas, refletindo a importância da alocação sequencial em linguagens de programação de alto nível e suas aplicações no desenvolvimento de software.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# lista linear em alocação sequencial
const lista = [1, 2, 3, 4, 5];

# acesso aleatório
console.log(lista[2]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora que temos uma compreensão clara sobre o que são listas lineares, podemos considerá-las como os fundamentos básicos das estruturas de dados. Dentro do universo das listas sequenciais, existem várias operações fundamentais que nos permitem manipulá-las de forma eficaz. Entre essas operações, destacam-se o acesso a elementos específicos, a inserção de novos elementos, a remoção de elementos existentes, a combinação de duas ou mais listas lineares em uma única lista, além da capacidade de dividir uma lista linear em várias listas menores.&lt;/p&gt;

&lt;p&gt;Em linguagens de programação de alto nível, como JavaScript e Python, essas funcionalidades já estão amplamente implementadas por meio de bibliotecas e construções da linguagem, permitindo que os desenvolvedores as utilizem sem a necessidade de compreender detalhadamente como estão implementadas internamente. Isso simplifica significativamente o processo de desenvolvimento de software, mas pode também obscurecer o entendimento dos princípios fundamentais que regem essas operações.&lt;/p&gt;

&lt;p&gt;No entanto, ao mergulharmos na programação com uma linguagem como C, que oferece um controle mais granular sobre a memória e as estruturas de dados, temos a oportunidade de implementar manualmente essas operações com listas lineares. Isso não apenas nos permite entender os mecanismos internos por trás de cada operação, mas também apreciar a complexidade e a elegância envolvidas na gestão eficiente de dados. Através dessa abordagem mais fundamentada, podemos explorar em profundidade como as listas são organizadas na memória, como as operações de inserção e remoção afetam a estrutura de dados e como a combinação e divisão de listas são realizadas, proporcionando uma compreensão mais rica e completa do funcionamento das estruturas de dados.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Com uma base sólida agora estabelecida sobre o que são listas lineares, você pode estar se perguntando como podemos implementar essas funcionalidades essenciais. A linguagem C, com seu controle detalhado sobre estruturas de dados e gerenciamento de memória, serve como uma ferramenta ideal para essa exploração. No entanto, dedicaremos um post exclusivo para mergulhar nessa implementação, pois introduzir esses conceitos aqui tornaria nosso diálogo excessivamente longo. O foco deste artigo foi estabelecer uma compreensão clara das listas lineares e suas operações fundamentais.&lt;/p&gt;

&lt;p&gt;Fique atento ao próximo artigo, onde colocaremos a teoria em prática, implementando algumas dessas operações críticas de listas na linguagem C. Prometo que será uma jornada enriquecedora e esclarecedora, ideal para quem deseja aprofundar seu entendimento sobre estruturas de dados de uma maneira prática e aplicada.&lt;/p&gt;

&lt;p&gt;Espero sinceramente que este artigo tenha sido tanto útil quanto inspirador. Entender estruturas de dados foi, e às vezes ainda é, um desafio para mim, mas é indiscutivelmente um dos pilares mais importantes da ciência da computação. Continuemos juntos nesta jornada de aprendizado. Até nosso próximo encontro, desejo-lhe sucesso e inspiração na sua aventura pelo fascinante mundo das estruturas de dados. Que a força esteja com você&lt;/p&gt;

</description>
    </item>
    <item>
      <title>O Papel do Back-end no Desenvolvimento Front-end: Introdução à Arquitetura BFF</title>
      <dc:creator>Gabriel Teixeira da Silva</dc:creator>
      <pubDate>Thu, 25 Jan 2024 21:37:11 +0000</pubDate>
      <link>https://dev.to/gabrielteixeira44/o-papel-do-back-end-no-desenvolvimento-front-end-introducao-a-arquitetura-bff-5e0h</link>
      <guid>https://dev.to/gabrielteixeira44/o-papel-do-back-end-no-desenvolvimento-front-end-introducao-a-arquitetura-bff-5e0h</guid>
      <description>&lt;p&gt;Como um entusiasta do front-end, sempre encontrei alegria e desafios em equal medida ao trabalhar com interfaces de usuário e a experiência do usuário. No entanto, recentemente me deparei com um desafio intrigante: mergulhar no mundo do back-end, especificamente no desenvolvimento de um BFF (Back For Front-end). Inicialmente, me vi confuso, questionando o que exatamente seria um BFF e como ele se encaixaria no ecossistema do desenvolvimento web. À medida que me aventurei neste novo território, percebi que estava não só expandindo minhas habilidades, mas também ganhando uma compreensão mais profunda de como o back-end pode potencializar e transformar experiências no front-end. Este artigo é um relato dessa jornada, uma introdução à arquitetura BFF e um olhar sobre como ela redefine o papel do back-end no desenvolvimento front-end.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mas afinal, o que é um BFF?
&lt;/h2&gt;

&lt;p&gt;Acompanhe-me nesta exploração e vamos descobrir juntos. BFF é um acrônimo para Backend For Frontend. Essencialmente, trata-se de um componente de back-end que tem a missão de prover os dados necessários para cada front-end da aplicação. Funcionando como um 'meio de campo', ele facilita a comunicação entre os front-ends e os diferentes back-ends em uma aplicação baseada em microsserviços. Isso otimiza a comunicação e o processamento de dados entre o servidor e o cliente, simplificando o desenvolvimento no front-end e contribuindo para uma experiência de usuário mais fluida e eficiente.&lt;/p&gt;

&lt;p&gt;A arquitetura BFF vai além de simplesmente fornecer dados; ela permite uma customização fina e adaptativa das respostas para diferentes tipos de front-end, seja um aplicativo móvel, uma web app ou até mesmo dispositivos IoT. Isso significa que, em vez de um front-end ter que se adaptar a uma variedade de serviços de back-end, é o BFF que se molda para atender às necessidades específicas de cada interface. Esta abordagem resulta em um código mais limpo e modular no front-end, reduzindo a complexidade e aumentando a eficiência do desenvolvimento. Além disso, o BFF pode desempenhar um papel vital na implementação de políticas de segurança, autenticação e autorização, agindo como um guardião que assegura que apenas os dados apropriados sejam entregues a cada cliente. A adesão à arquitetura BFF não apenas melhora o desempenho e a usabilidade das aplicações, mas também potencializa uma arquitetura de software mais sustentável e escalável a longo prazo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mas onde exatamente o BFF se encaixa no panorama do desenvolvimento de software?
&lt;/h2&gt;

&lt;p&gt;Agora que compreendemos o que é um BFF, seu propósito e os problemas que ele resolve, vamos ilustrar seu uso com um exemplo concreto. Imaginemos, por exemplo, uma aplicação para gestão de contas bancárias. Esta aplicação poderia ser estruturada dividindo-se em contextos menores e independentes, o que facilita a manutenção e aprimora o gerenciamento da escalabilidade de cada parte do sistema.&lt;/p&gt;

&lt;p&gt;Vamos imaginar a seguinte divisão:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fujjj9zup15yupa6etv71.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fujjj9zup15yupa6etv71.png" alt="Um retângulo com o título conta bancaria e dentro dele três eclipses representando a conta, saldo e usuário"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nessa estrutura, cada aspecto da aplicação é tratado como um serviço distinto, caracterizado por sua autonomia e independência. Isso permite o isolamento efetivo das regras de negócio pertinentes a cada área, resultando em serviços mais focados e coesos.&lt;/p&gt;

&lt;p&gt;Neste cenário, a nossa aplicação de gestão de contas bancárias poderia ser segmentada em três principais microsserviços: um para o extrato bancário, outro dedicado à gestão de saldo e um terceiro para gerenciamento de usuários. Essa separação permite que cada microsserviço opere de maneira independente, o que é uma grande vantagem, especialmente em termos de estabilidade e manutenção. Se um serviço enfrenta problemas, isso não afeta diretamente os outros, minimizando interrupções e melhorando a resiliência geral do sistema.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foxowqn1941ev58memfko.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foxowqn1941ev58memfko.png" alt="Um retângulo com o título conta bancaria e dentro dele três eclipses representando a conta, saldo e usuário e cada eclipse com uma seta que aponta para um retângulo que representa o banco de dados"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Neste exemplo de aplicação bancária, consideremos a tela inicial onde informações cruciais são exibidas - informações estas que são fornecidas por diferentes serviços: extrato, saldo e usuário. Aqui surge um desafio comum em arquiteturas baseadas em microsserviços: ao invés de uma fonte de dados centralizada, temos dados vitais dispersos em três fontes distintas. Cada serviço opera independentemente, armazenando e gerenciando suas próprias informações, o que pode complicar a coleta e a exibição harmoniosa desses dados na interface do usuário.&lt;/p&gt;

&lt;p&gt;Uma abordagem para lidar com os dados dispersos em nossa aplicação bancária seria fazer com que o front-end execute simultaneamente três requisições para os respectivos microsserviços, buscando as informações necessárias para a tela inicial. Embora esta solução possa parecer viável, ela introduz uma série de complicações arquiteturais.&lt;/p&gt;

&lt;p&gt;Primeiramente, isso resulta em uma confusão de responsabilidades: o front-end, que deveria focar apenas na renderização, acaba assumindo também o controle de fluxo das comunicações com os diversos microsserviços. Isso não só aumenta o acoplamento entre front-end e back-end, dificultando os testes, como também pode retardar a renderização da tela inicial devido à sobrecarga de tarefas.&lt;/p&gt;

&lt;p&gt;Além disso, ao exigir que o front-end gerencie três requisições paralelas, impõe-se uma carga adicional ao lado do cliente. Ele precisa não apenas renderizar a tela, mas também coordenar essas múltiplas requisições, o que pode afetar a performance e a eficiência da aplicação.&lt;/p&gt;

&lt;p&gt;Aqui é onde o BFF se torna essencial. Em vez de o aplicativo bancário realizar três requisições separadas para cada microsserviço a fim de construir a página inicial, ele poderia simplesmente fazer uma única requisição a um BFF. O BFF, então, se encarrega de comunicar-se com os microsserviços necessários, coletando e compilando os dados para a montagem da tela.&lt;/p&gt;

&lt;p&gt;Esta solução supera os desafios de sobrecarregar o front-end com múltiplas requisições. Ela mantém as fontes de dados ocultas e indistintas para os componentes de front-end, simplificando a estrutura de consumo de dados.&lt;/p&gt;

&lt;p&gt;Além disso, se for necessário reestruturar onde os dados, como os detalhes do extrato, são armazenados ou combiná-los com informações de outros microsserviços, essa mudança ocorre de forma transparente para o aplicativo. O ajuste é feito apenas no BFF, que continua entregando as informações ao front-end da mesma forma, independentemente das mudanças internas nos serviços de back-end.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foqdqc26ah8x1jqpn37nx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foqdqc26ah8x1jqpn37nx.png" alt="Um retângulo com o título conta bancaria e dentro dele três eclipses representando a conta, saldo e usuário e cada eclipse com uma seta que aponta para um retângulo que representa o banco de dados e um retângulo representando o BFF"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Considerações Finais: Navegando Pelos Detalhes e Desafios do BFF
&lt;/h2&gt;

&lt;p&gt;Os BFFs são essenciais para fornecer dados específicos para diferentes interfaces de usuário, como web e mobile, em uma aplicação. Eles permitem customizar as informações conforme a necessidade de cada cliente, podendo haver BFFs distintos para diferentes tipos de front-end. No exemplo de uma aplicação bancária, um BFF poderia ser projetado especificamente para a web, necessitando de mais dados, enquanto outro seria para mobile, com menos dados requeridos. No entanto, usar um BFF único para ambas as interfaces pode levar ao over-fetching, onde, por exemplo, a interface mobile recebe mais dados do que necessita. Isso resulta em esforços desnecessários para processar dados irrelevantes e um consumo excessivo de banda larga e dados, afetando a eficiência do aplicativo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Espero que este artigo tenha sido útil e inspirador para você. Embora explorar o back-end tenha sido um desafio, a jornada tem sido extremamente gratificante e cheia de aprendizados. Nos artigos futuros, estou ansioso para compartilhar mais de minhas experiências com vocês, continuando a aprimorar nosso conhecimento juntos. Em breve, trarei também conteúdo sobre acessibilidade na web, um tema igualmente importante e fascinante. Agradeço a todos que acompanharam este artigo. Estou sempre aberto a sugestões e dúvidas; afinal, o aprendizado é um caminho que trilhamos juntos. Até a próxima, e que a força esteja com você na sua própria aventura no mundo do desenvolvimento!&lt;/p&gt;

&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://philcalcado.com/2015/09/18/the_back_end_for_front_end_pattern_bff.html" rel="noopener noreferrer"&gt;The Back-end for Front-end Pattern (BFF)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://bff-patterns.com/" rel="noopener noreferrer"&gt;BFF Patterns&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.diva-portal.org/smash/record.jsf?pid=diva2%3A1776124&amp;amp;dswid=612" rel="noopener noreferrer"&gt;Back-end for Front-end Connectorto Reduce Development Time: A Proof of Concept Project&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Compreendendo as Diferenças entre useEffect, useMemo e useCallback</title>
      <dc:creator>Gabriel Teixeira da Silva</dc:creator>
      <pubDate>Thu, 07 Sep 2023 15:17:06 +0000</pubDate>
      <link>https://dev.to/gabrielteixeira44/compreendendo-as-diferencas-entre-useeffect-usememo-e-usecallback-22cf</link>
      <guid>https://dev.to/gabrielteixeira44/compreendendo-as-diferencas-entre-useeffect-usememo-e-usecallback-22cf</guid>
      <description>&lt;h2&gt;
  
  
  Mas, o que é um Hook?
&lt;/h2&gt;

&lt;p&gt;No React, um hook é uma função especial que permite que você "ligue-se" a recursos e funcionalidades do React em componentes funcionais. Os hooks foram introduzidos no React 16.8 para permitir o uso de estados e outros recursos anteriormente disponíveis apenas em componentes de classe em componentes funcionais.&lt;br&gt;
Os hooks permitem que você adicione funcionalidades de gerenciamento de estado, efeitos colaterais, contexto, referências e muito mais aos seus componentes funcionais.&lt;br&gt;
Neste artigo, abordaremos as distinções entre três hooks essenciais do React: &lt;strong&gt;useEffect&lt;/strong&gt;, &lt;strong&gt;useMemo&lt;/strong&gt; e &lt;strong&gt;useCallback&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  useEffect
&lt;/h2&gt;

&lt;p&gt;O &lt;strong&gt;useEffect&lt;/strong&gt; trata principalmente de lidar com efeitos colaterais em componentes React. Efeitos colaterais geralmente incluem operações como buscar dados, manipular o DOM e gerenciar assinaturas. Aqui está uma análise das suas principais características:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Propósito: O propósito principal do &lt;strong&gt;useEffect&lt;/strong&gt; é executar código que tenha efeitos colaterais. Esses efeitos colaterais podem estar relacionados à renderização do componente ou a mudanças em suas dependências.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Uso: Você fornece uma função de retorno para o &lt;strong&gt;useEffect&lt;/strong&gt;, e o React executa essa função depois que o componente foi renderizado ou quando as dependências especificadas foram alteradas.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Casos de Uso Típicos: O &lt;strong&gt;useEffect&lt;/strong&gt; é comumente utilizado para tarefas como buscar dados, configurar e limpar ouvintes de eventos e realizar ações em resposta a mudanças em props ou estado.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Exemplo de Uso
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState, useEffect } from 'react';

function ExemploUseEffect() {
  // Defina um estado para armazenar uma contagem
  const [count, setCount] = useState(0);

  // useEffect é usado para realizar efeitos colaterais
  useEffect(() =&amp;gt; {
    // Atualize o título da página com a contagem atual
    document.title = `Contagem: ${count}`;

    // Este código será executado após cada renderização
    // e sempre que 'count' for alterado.

    // É uma boa prática retornar uma função de limpeza
    // se você precisar desfazer algum efeito.
    return () =&amp;gt; {
      document.title = 'Aplicação React'; // Reverter o título
    };
  }, [count]); // Especifique as dependências aqui

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;p&amp;gt;Contagem: {count}&amp;lt;/p&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; setCount(count + 1)}&amp;gt;Incrementar&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default ExemploUseEffect;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste exemplo, usamos o &lt;strong&gt;useEffect&lt;/strong&gt; para atualizar o título da página com a contagem atual toda vez que o estado count for alterado. Observamos que passamos [count] como um segundo argumento para o useEffect. Isso especifica as dependências do efeito, ou seja, quando o efeito deve ser executado novamente. Neste caso, o efeito será acionado sempre que count mudar.&lt;/p&gt;

&lt;p&gt;Além disso, fornecemos uma função de retorno no &lt;strong&gt;useEffect&lt;/strong&gt;. Esta função será chamada quando o componente for desmontado ou quando a dependência count mudar novamente. É uma prática recomendada para fazer a limpeza de efeitos quando eles não são mais necessários.&lt;/p&gt;

&lt;p&gt;Quando você clicar no botão "Incrementar", a contagem aumentará e o título da página será atualizado de acordo com o valor atual da contagem.&lt;/p&gt;

&lt;h2&gt;
  
  
  useMemo
&lt;/h2&gt;

&lt;p&gt;O useMemo é inteiramente voltado para a memorização. A memorização é uma técnica na qual o resultado de uma função ou expressão custosa é armazenado em cache, de modo que seja recalculado apenas quando suas dependências mudam. Aqui está uma análise das suas principais características:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Propósito: O &lt;strong&gt;useMemo&lt;/strong&gt; é usado para memorizar (armazenar em cache) o resultado de uma função ou expressão. Isso pode melhorar o desempenho ao evitar cálculos desnecessários.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Uso: Você fornece uma função e uma matriz de dependências para o &lt;strong&gt;useMemo&lt;/strong&gt;. O React executa a função e armazena em cache seu resultado. Se as dependências mudarem, a função é reexecutada e o resultado é atualizado.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Casos de Uso Típicos: A memorização é útil para cálculos computacionalmente custosos ou para evitar renderizações desnecessárias de componentes.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Exemplo de Uso
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState, useMemo } from 'react';

function ExemploUseMemo() {
  // Defina dois estados para armazenar números
  const [num1, setNum1] = useState(5);
  const [num2, setNum2] = useState(10);

  // Use useMemo para calcular a soma dos números apenas quando eles mudarem
  const soma = useMemo(() =&amp;gt; {
    console.log('Calculando a soma...');
    return num1 + num2;
  }, [num1, num2]); // Dependências

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;p&amp;gt;Número 1: {num1}&amp;lt;/p&amp;gt;
      &amp;lt;p&amp;gt;Número 2: {num2}&amp;lt;/p&amp;gt;
      &amp;lt;p&amp;gt;Soma: {soma}&amp;lt;/p&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; setNum1(num1 + 1)}&amp;gt;Incrementar Número 1&amp;lt;/button&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; setNum2(num2 + 1)}&amp;gt;Incrementar Número 2&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default ExemploUseMemo;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste exemplo, estamos usando o &lt;strong&gt;useMemo&lt;/strong&gt; para calcular a soma dos números num1 e num2. O cálculo da soma é uma operação simples, mas suponha que tivéssemos uma operação computacionalmente cara em vez disso.&lt;/p&gt;

&lt;p&gt;O &lt;strong&gt;useMemo&lt;/strong&gt; recebe uma função de cálculo e uma matriz de dependências como argumentos. A função de cálculo será executada apenas quando uma das dependências (num1 ou num2) mudar. Isso significa que a soma só será recalculada quando um dos números for incrementado.&lt;/p&gt;

&lt;p&gt;Dentro da função de cálculo, você pode realizar qualquer operação que desejar. Neste exemplo, usamos um console.log para demonstrar quando a soma está sendo calculada.&lt;/p&gt;

&lt;p&gt;Ao clicar nos botões "Incrementar Número 1" ou "Incrementar Número 2", apenas o número relevante é atualizado, e a soma é recalculada somente quando necessário, graças ao uso do useMemo. Isso ajuda a evitar cálculos desnecessários e melhora o desempenho do componente.&lt;/p&gt;

&lt;h2&gt;
  
  
  useCallback
&lt;/h2&gt;

&lt;p&gt;O &lt;strong&gt;useCallback&lt;/strong&gt; está intimamente relacionado ao &lt;strong&gt;useMemo&lt;/strong&gt;, mas foca na memorização de funções em vez de valores. É particularmente útil ao passar funções de retorno de chamada para componentes filhos. Aqui está uma análise das suas principais características:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Propósito: &lt;strong&gt;useCallback&lt;/strong&gt; é usado para memorizar (armazenar em cache) uma função de modo que ela seja recriada apenas quando suas dependências mudam. Isso pode otimizar o desempenho ao passar funções de retorno de chamada como propriedades.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Uso: Você fornece uma função e uma matriz de dependências para &lt;strong&gt;useCallback&lt;/strong&gt;. O React retorna uma versão memorizada da função. Se as dependências mudarem, uma nova função memorizada é criada.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Casos de Uso Típicos: É comumente usado para memorizar funções de retorno de chamada, especialmente ao passar essas funções para componentes filhos.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Exemplo de Uso
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState, useCallback } from 'react';

function ExemploUseCallback() {
  // Defina um estado para armazenar um contador
  const [contador, setContador] = useState(0);

  // Defina uma função de retorno de chamada para incrementar o contador
  const incrementarContador = useCallback(() =&amp;gt; {
    setContador(contador + 1);
  }, [contador]); // Dependência: contador

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;p&amp;gt;Contador: {contador}&amp;lt;/p&amp;gt;
      &amp;lt;button onClick={incrementarContador}&amp;gt;Incrementar Contador&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default ExemploUseCallback;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste exemplo, estamos usando o &lt;strong&gt;useCallback&lt;/strong&gt; para memorizar a função &lt;strong&gt;incrementarContador&lt;/strong&gt;. A função &lt;strong&gt;incrementarContador&lt;/strong&gt; simplesmente incrementa o valor do contador quando o botão é clicado.&lt;/p&gt;

&lt;p&gt;Observe que passamos [contador] como uma matriz de dependência para &lt;strong&gt;useCallback&lt;/strong&gt;. Isso significa que a função &lt;strong&gt;incrementarContador&lt;/strong&gt; será memorizada e recriada apenas quando a dependência contador mudar. Isso é útil para evitar que a função seja recriada em cada renderização, economizando recursos.&lt;/p&gt;

&lt;p&gt;Ao clicar no botão "Incrementar Contador", o valor do contador aumenta, e a função incrementarContador é chamada sem ser recriada desnecessariamente. Isso melhora a eficiência e é particularmente útil ao passar essa função como propriedade para componentes filhos, onde a memorização pode economizar ciclos de renderização.&lt;/p&gt;

&lt;h2&gt;
  
  
  Principais Diferenças
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;useEffect&lt;/strong&gt; é usado para lidar com efeitos colaterais e executar código após a renderização ou quando certas dependências mudam.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;useMemo&lt;/strong&gt; é usado para memorizar o resultado de uma função ou expressão a fim de evitar recalculos desnecessários.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;useCallback&lt;/strong&gt; é usado para memorizar funções, sendo especialmente útil para otimizar componentes filhos que dependem de funções de retorno de chamada.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Todos os três hooks recebem uma matriz de dependências. Quando essas dependências mudam, &lt;strong&gt;useEffect&lt;/strong&gt; executa sua função de efeito, &lt;strong&gt;useMemo&lt;/strong&gt; recalcula o valor e &lt;strong&gt;useCallback&lt;/strong&gt; recria a função memorizada.&lt;/p&gt;

&lt;p&gt;Em resumo, esses hooks têm propósitos distintos e são ferramentas valiosas para gerenciar diferentes aspectos dos seus componentes React. Compreender quando e como usar &lt;strong&gt;useEffect&lt;/strong&gt;, &lt;strong&gt;useMemo&lt;/strong&gt; e &lt;strong&gt;useCallback&lt;/strong&gt; podem contribuir para tornar seus aplicativos React mais eficientes e tornar a&lt;br&gt;
manutenção mais simples.&lt;/p&gt;

&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://react.dev/reference/react"&gt;Documentação React&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://react.dev/reference/react/useEffect"&gt;Documentação useEffect&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://react.dev/reference/react/useMemo"&gt;Documentação useMemo&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://react.dev/reference/react/useCallback"&gt;Documentação useCallback&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
  </channel>
</rss>
