<?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: Guilherme Selair</title>
    <description>The latest articles on DEV Community by Guilherme Selair (@guiselair).</description>
    <link>https://dev.to/guiselair</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%2F441050%2Fd6e7ba2d-7647-4bc8-8bd8-35fbfeb65356.jpg</url>
      <title>DEV Community: Guilherme Selair</title>
      <link>https://dev.to/guiselair</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/guiselair"/>
    <language>en</language>
    <item>
      <title>Interceptando Requisições com DevTools</title>
      <dc:creator>Guilherme Selair</dc:creator>
      <pubDate>Thu, 24 Oct 2024 12:00:00 +0000</pubDate>
      <link>https://dev.to/guiselair/interceptando-requisicoes-no-devtools-39jl</link>
      <guid>https://dev.to/guiselair/interceptando-requisicoes-no-devtools-39jl</guid>
      <description>&lt;p&gt;&lt;strong&gt;Salve Salve! 🖖&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Como mencionei no primeiro artigo da série, a ferramenta que usamos todos os dias como &lt;em&gt;dev frontend&lt;/em&gt; é o navegador. Esta série de artigos tem como objetivo revelar explicações e funcionalidades escondidas dentro dele.&lt;/p&gt;

&lt;p&gt;Muitas vezes, precisamos desenvolver o &lt;em&gt;frontend&lt;/em&gt; de uma aplicação enquanto o &lt;em&gt;backend&lt;/em&gt; ainda está em construção. Para esses casos, a funcionalidade de sobrescrita de respostas e &lt;em&gt;headers&lt;/em&gt; HTTP pode ser uma grande aliada.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Este post não é uma documentação oficial nem pretende cobrir tudo. Ele traz a minha visão sobre a funcionalidade e como ela pode facilitar o nosso dia a dia como devs.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Essa ferramenta do &lt;em&gt;DevTools&lt;/em&gt; permite interceptar requisições HTTP e modificar seu conteúdo e cabeçalhos. Com ela, você consegue testar diferentes cenários e desenvolver sua aplicação &lt;em&gt;frontend&lt;/em&gt; mesmo que a &lt;em&gt;API&lt;/em&gt; ainda não esteja pronta, desde que o contrato de comunicação entre as pontas esteja definido.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como usar?
&lt;/h2&gt;

&lt;p&gt;Aqui vai um guia básico para ativar e aproveitar essa funcionalidade:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Abra o Chrome DevTools&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Pressione &lt;code&gt;F12&lt;/code&gt; ou clique com o botão direito no site e selecione “Inspecionar”.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No painel Network&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Selecione a requisição que você deseja modificar, clique com o botão direito e escolha a opção “Substituir conteúdo” ou “Substituir cabeçalho”.&lt;/li&gt;
&lt;li&gt;Na primeira vez que você fizer isso, será necessário escolher uma pasta no seu sistema para armazenar os arquivos com os conteúdos fictícios.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No painel Sources&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Caso tenha selecionado “Substituir conteúdo”, insira o conteúdo que será retornado na resposta da requisição.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pronto! Agora é só utilizar.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Obs: Vale ressaltar que, enquanto houver alguma substituição ativa, o cache local é desativado.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Show me the code!
&lt;/h2&gt;

&lt;p&gt;Para exemplificar como essa ferramenta funciona, vou interceptar &lt;strong&gt;um endpoint que ainda não está pronto&lt;/strong&gt; e fazer com que ele retorne uma resposta fictícia para testar o preenchimento dos campos de um formulário no &lt;em&gt;frontend&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Abaixo, vemos que esse endpoint ainda não existe, e por isso a API está retornando um 404:&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2Farticles%2Fl4opf0kijyz2f14z159q.png" class="article-body-image-wrapper"&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%2Farticles%2Fl4opf0kijyz2f14z159q.png" alt="404" width="800" height="150"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O endpoint em questão busca os detalhes de uma despesa específica e preenche os campos do formulário de edição na tela.&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2Farticles%2Fgyz3npeplktzj3bgsh4k.png" class="article-body-image-wrapper"&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%2Farticles%2Fgyz3npeplktzj3bgsh4k.png" alt="formulario em branco" width="800" height="523"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Selecionando a requisição que queremos modificar e clicando em “Substituir conteúdo”, colamos um conteúdo fictício de uma despesa, respeitando o contrato da API. Pronto!&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2Farticles%2Fo9qh6dshwe29hgv5dw9e.gif" class="article-body-image-wrapper"&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%2Farticles%2Fo9qh6dshwe29hgv5dw9e.gif" alt="fluxo completo" width="800" height="399"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nem preciso dizer que há muitas outras possibilidades de uso para essa ferramenta, como testar diferentes tipos de erros, onde cada um exibe uma mensagem diferente na tela, entre outros cenários.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Obs: Vale um lembrete rápido: sempre que o DevTools estiver fechado, as requisições funcionam normalmente. Elas só serão afetadas quando o DevTools estiver aberto.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Top demais!! 😻
&lt;/h2&gt;

&lt;p&gt;E aí, curtiu? Espero que essa funcionalidade de sobrescrita ajude a simplificar seus testes e simulações no dia a dia. Se ficou alguma dúvida ou quiser trocar ideias, manda aí nos comentários que a gente continua a conversa!&lt;/p&gt;

&lt;p&gt;See you soon!&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Documentação oficial: &lt;a href="https://developer.chrome.com/docs/devtools/overrides?hl=pt-br" rel="noopener noreferrer"&gt;Chrome DevTools Overrides&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devtools</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Automatizando Formulários com DevTools</title>
      <dc:creator>Guilherme Selair</dc:creator>
      <pubDate>Fri, 18 Oct 2024 12:40:00 +0000</pubDate>
      <link>https://dev.to/guiselair/automatizando-formularios-com-devtools-2p9e</link>
      <guid>https://dev.to/guiselair/automatizando-formularios-com-devtools-2p9e</guid>
      <description>&lt;p&gt;&lt;strong&gt;Salve Salve!&lt;/strong&gt; 🖖 &lt;/p&gt;

&lt;p&gt;Uma das ferramentas mais utilizadas no dia a dia do &lt;strong&gt;dev frontend&lt;/strong&gt; é o navegador. Por isso, é importante conhecê-lo bem e conseguir extrair o máximo de seu potencial. Este é o primeiro artigo da série &lt;strong&gt;Explorando seu navegador&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Meu objetivo aqui é compartilhar com vocês um pouquinho do que sei sobre a &lt;strong&gt;funcionalidade de gravação do DevTools&lt;/strong&gt; e como ela pode nos ajudar a automatizar processos repetitivos.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Este post não serve como documentação oficial e não tem o objetivo de ser o mais completo possível. Ele representa apenas a minha visão sobre a funcionalidade.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;O &lt;strong&gt;DevTools&lt;/strong&gt;, ou ferramentas de desenvolvimento, está presente em todos os principais navegadores, como Firefox, Edge e Safari, mas hoje vamos focar no &lt;strong&gt;Chrome DevTools&lt;/strong&gt;. Isso porque o Google Chrome é o navegador mais utilizado no mundo, responsável por cerca de &lt;strong&gt;63%&lt;/strong&gt; do tráfego global da internet. Ele permite aos desenvolvedores inspecionar, editar e depurar o código de suas aplicações web em tempo real.&lt;/p&gt;

&lt;p&gt;Você já deve ter se cansado de preencher os mesmos formulários repetidamente durante o desenvolvimento de uma aplicação web, e é aí que entra a funcionalidade de “Gravador”. Ela permite capturar as interações com o seu site, como cliques, preenchimento de formulários e navegações. Depois, você pode reproduzir essas interações em uma simulação real, ideal para testes repetitivos ou demonstrações.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como Usar?
&lt;/h2&gt;

&lt;p&gt;Aqui vai um passo a passo rapidinho para começar a automação dos seus formulários:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Abra o Chrome DevTools&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Aperte &lt;code&gt;F12&lt;/code&gt; ou clique com o botão direito no site e escolha “Inspecionar”.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Acesse a aba Gravador&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Com o DevTools aberto, vá para a aba &lt;strong&gt;Gravador&lt;/strong&gt; (Recorder). Se não estiver vendo, clique nos três pontinhos à direita das abas e ative-a!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inicie uma nova gravação&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Clique em &lt;strong&gt;Nova Gravação&lt;/strong&gt;. Nomeie como quiser e pronto, já pode começar a registrar!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Preencha o Formulário&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Faça suas interações normalmente. A cada clique, o DevTools estará capturando seus passos, desde o preenchimento de campos de texto até o clique em botões de envio.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Finalizou? Pare e Reproduza!&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Quando terminar, clique em &lt;strong&gt;Parar&lt;/strong&gt;. Agora você pode ver o passo a passo do que gravou e reproduzi-lo quantas vezes quiser.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Show me the code!
&lt;/h2&gt;

&lt;p&gt;Vou exemplificar como funciona na prática no formulário de criação de despesas da aplicação &lt;em&gt;finance-app&lt;/em&gt;. Primeiro, seguindo os passos acima, iniciamos a gravação e preenchemos o formulário manualmente.&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%2Fzgt9if8k2awu9zz866b1.gif" 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%2Fzgt9if8k2awu9zz866b1.gif" alt="step1" width="1150" height="576"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Após terminar de preencher o formulário, basta clicar no botão “Encerrar gravação” para que a automação do formulário esteja pronta. Agora, toda vez que você precisar testar esse formulário, é só clicar na gravação realizada e dar play.&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%2Fcvqebiun7ng2gunspccj.gif" 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%2Fcvqebiun7ng2gunspccj.gif" alt="step2" width="850" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Show! Claro, este formulário é pequeno, mas para formulários grandes isso é uma mão na roda! Há outras opções que também podem ser exploradas, como adicionar alguma limitação de rede durante a reprodução da gravaçã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%2Fjejxc1mrooosunrra36v.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%2Fjejxc1mrooosunrra36v.png" alt="Image description" width="535" height="332"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👉🏻 Todas as opções disponíveis você pode conferir na documentação oficial da funcionalidade (&lt;a href="https://developer.chrome.com/docs/devtools/recorder/overview?hl=pt-br" rel="noopener noreferrer"&gt;link&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nem preciso falar das outras possibilidades de uso que essa funcionalidade oferece, né? Utilizei o preenchimento de formulários como exemplo real, mas ela se encaixa muito bem para automações em geral dentro da aplicação, até mesmo em testes E2E.&lt;/p&gt;

&lt;h2&gt;
  
  
  Top demais!! 😻
&lt;/h2&gt;

&lt;p&gt;Chegamos ao fim de mais um post e então, gostou?&lt;/p&gt;

&lt;p&gt;Espero ter conseguido te apresentar algo novo e interessante para usar em seus projetos no dia a dia. Achou que eu falei algo errado? Ficou com dúvidas? Vamos discutir melhor nos comentários.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;See you soon!&lt;/strong&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Documentação oficial: &lt;a href="https://developer.chrome.com/docs/devtools/recorder/overview?hl=pt-br" rel="noopener noreferrer"&gt;https://developer.chrome.com/docs/devtools/recorder/overview?hl=pt-br&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>devtools</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Propriedade as em componentes React com Typescript</title>
      <dc:creator>Guilherme Selair</dc:creator>
      <pubDate>Tue, 13 Dec 2022 00:17:37 +0000</pubDate>
      <link>https://dev.to/guiselair/propriedade-as-em-componentes-react-com-typescript-3p8a</link>
      <guid>https://dev.to/guiselair/propriedade-as-em-componentes-react-com-typescript-3p8a</guid>
      <description>&lt;p&gt;Salve Salve! 🖖  &lt;/p&gt;

&lt;p&gt;Vou compartilhar com vocês o pouquinho que eu sei sobre tipagens condicionais e espero conseguir fazer você entender mais sobre isso.&lt;/p&gt;

&lt;h3&gt;
  
  
  Nota
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Este post não serve de documentação e não tem como objetivo ser o mais completo possível. Ele representa apenas a minha visão sobre a utilização de conditional types que obtive ao longo do tempo.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Não é de hoje que o Typescript vem se tornando cada vez mais utilizado no cenário do &lt;em&gt;frontend&lt;/em&gt;, muitos devs já começam seus projetos já com o Typescript habilitado (eu sou assim). &lt;/p&gt;

&lt;p&gt;Dando uma breve contextualizada. Typescript é um linguagem de programação fortemente tipada construída encima do Javascript. Tipar variáveis, objetos, funções, etc facilita demais no descobrimento de propriedades durante o desenvolvimento. &lt;/p&gt;

&lt;p&gt;Tipagens condicionais não são comumente utilizadas porém há casos de uso que elas se encaixam muito bem. Como o proprio nome já diz tudo, se trata de uma tipagem baseada em uma condição. Vou te mostrar um caso de uso que eu acho muito legal em um contexto &lt;strong&gt;react&lt;/strong&gt;, é um pouquinho mais avançado mas espero conseguir explicar direitinho 😀 &lt;/p&gt;

&lt;h2&gt;
  
  
  Show me the code!
&lt;/h2&gt;

&lt;p&gt;Sem mais enrolação vamos desenvolver durante este post a tipagem da propriedade &lt;code&gt;as&lt;/code&gt; do componente &lt;code&gt;Button&lt;/code&gt; em &lt;em&gt;react&lt;/em&gt;. Você já deve ter se deparado com algum componente de uma biblioteca de componentes como &lt;em&gt;ChakraUI&lt;/em&gt; e &lt;em&gt;MaterialUI&lt;/em&gt; a utilização dessa propriedade.&lt;/p&gt;

&lt;p&gt;Não pretendo implementar exatamente igual a essas bibliotecas mas vou exemplificar aqui como fazer uma tipagem condicional básica para satisfazer o componente. Basicamente o componente &lt;code&gt;Button&lt;/code&gt; poderá receber o nome de um elemento HTML que será o utilizado como &lt;em&gt;wrapper&lt;/em&gt; dentro do componente.&lt;/p&gt;

&lt;p&gt;Abaixo temos o código do componente sem tipagens:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="k"&gt;as&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="nx"&gt;restProps&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;Element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&lt;/span&gt;&lt;span class="dl"&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;Element&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;restProps&lt;/span&gt;&lt;span class="si"&gt;}&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="nc"&gt;Element&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;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&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="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;Button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Abrir&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&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;A partir desse código criaremos nossas tipagens. Vamos começar criando a tipagem do componente &lt;code&gt;Button&lt;/code&gt; como queremos utiliza-lo.&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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IButton&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;as&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Element&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;Acima temos a interface básica do nosso componente, a gente espera receber a propriedade &lt;code&gt;as&lt;/code&gt; com valor do elemento HTML que envolverá nosso botão. Além disso adicionei uma outra propriedade que será opcional mas sem mistérios nela, é só pra exemplificar com outras propriedades.&lt;/p&gt;

&lt;h3&gt;
  
  
  Desafio
&lt;/h3&gt;

&lt;p&gt;Aqui nos deparamos com nosso desafio. Queremos que quando o código abaixo for chamado:&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;as&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Enviar&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&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;No autocomplete das propriedades que este componente pode receber, deverá aparecer as propriedades do elemento &lt;em&gt;HTML&lt;/em&gt; que passamos na propriedade &lt;code&gt;as&lt;/code&gt;, ou seja, no exemplo, &lt;em&gt;button&lt;/em&gt;. Além das outras problemas que colocamos na interface &lt;code&gt;IButton&lt;/code&gt; .&lt;/p&gt;

&lt;h3&gt;
  
  
  Typescript Generics
&lt;/h3&gt;

&lt;p&gt;Precisamos entender mais algumas coisas a mais sobre Typescript. &lt;em&gt;Generics&lt;/em&gt; é uma forma de enviar tipos dinâmicos para dentro de alguma interface. Você já deve ter utilizado ele se você já trabalhou com &lt;em&gt;axios&lt;/em&gt;. Olha o código abaixo:&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;IResponseData&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;('https://github.com/guiselair')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste exemplo, foi passado um &lt;em&gt;generic&lt;/em&gt; informando qual será a tipagem do retorno da requisição &lt;em&gt;get&lt;/em&gt;. Utilizaremos desse principio para construir nossas tipagens condicionais.&lt;/p&gt;

&lt;p&gt;Além disso é possível fazer com &lt;em&gt;generics&lt;/em&gt; condições, mais ou menos assim, “Se for tal tipo, pega tal tipagem, senao, pega outra” ou até “Se o tipo foi este, pega este tipo”. Não se preocupe que abaixo vou explicar melhor.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tipando propriedade &lt;code&gt;as&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Vamos atualizar a interface do &lt;code&gt;IButton&lt;/code&gt;:&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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IButton&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;E&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ElementType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ElementType&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;as&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ElementType&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;Com o tipo acima, agora garantimos que o que for escrito dentro da propriedade &lt;code&gt;as&lt;/code&gt; será um elemento &lt;em&gt;HTML&lt;/em&gt; válido, caso não for um erro semelhante a este será exibido:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔥 Type '"div1"' is not assignable to type 'ElementType | undefined’&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A primeira parte do nosso desafio esta pronta, &lt;em&gt;tipar&lt;/em&gt; a propriedade &lt;code&gt;as&lt;/code&gt; . Agora temos que definir as tipagens das propriedade deste componente levando em consideração o valor recebido pelo &lt;code&gt;as&lt;/code&gt; .&lt;/p&gt;

&lt;h3&gt;
  
  
  Tipando &lt;code&gt;props&lt;/code&gt; do componente Button
&lt;/h3&gt;

&lt;p&gt;Para pegar todas as propriedades do elemento &lt;em&gt;HTML&lt;/em&gt; recebido precisamos utilizar um código meio complicadinho de entender mas vamos com calma. O código abaixo, faz uma condicional em formato de &lt;em&gt;generics&lt;/em&gt; e caso seja uma das opções (&lt;code&gt;keyof JSX.IntrinsicElements | React.JSXElementConstructor&amp;lt;any&amp;gt;&lt;/code&gt;) retorna uma tipagem do tipo &lt;code&gt;JSX.LibraryManagedAttributes&lt;/code&gt; . &lt;/p&gt;

&lt;p&gt;Segunda a documentação da tipagem, este tipo &lt;code&gt;JSX.LibraryManagedAttributes&lt;/code&gt; define uma transformação nas &lt;code&gt;props&lt;/code&gt; do componente. Então basicamente, este tipo vai unir outros tipos e retornar uma união entre eles.&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="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;PropsOf&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;
  &lt;span class="nx"&gt;E&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;JSX&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;IntrinsicElements&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;JSXElementConstructor&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSX&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LibraryManagedAttributes&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ComponentPropsWithRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;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;em&gt;Obs: Estou simplificando aqui a explicação por dois motivos, este código você não precisara decorar e este é o conhecimento que eu tenho até então sobre isso&lt;/em&gt; 😄&lt;/p&gt;

&lt;p&gt;Agora que já conseguimos pegar todos os tipos do elemento &lt;em&gt;HTML&lt;/em&gt; precisamos mesclar o tipo &lt;code&gt;IButton&lt;/code&gt; com as as propriedades do elemento. Para isso vamos criar um novo &lt;em&gt;type&lt;/em&gt;:&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="k"&gt;export&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;IButtonProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;E&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ElementType&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;IButton&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;
  &lt;span class="nx"&gt;Omit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PropsOf&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;E&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;keyof&lt;/span&gt; &lt;span class="nx"&gt;IButton&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O código acima extende a interface &lt;code&gt;IButton&lt;/code&gt; com o resultado da expressão (&lt;code&gt;Omit&amp;lt;PropsOf&amp;lt;E&amp;gt;, keyof IButton&amp;gt;&lt;/code&gt; ). O auxiliar &lt;code&gt;Omit&lt;/code&gt; remove da tipagem &lt;code&gt;PropsOf&amp;lt;E&amp;gt;&lt;/code&gt; as chaves do tipo &lt;code&gt;IButton&lt;/code&gt; para não haver conflitos de nomes de propriedades, isso poderia geral erros no Typescript.&lt;/p&gt;

&lt;p&gt;Com este trecho pronto agora basta a gente adicionar este novo tipo como retorno do nosso componente. Isso é feito no trecho de código abaixo:&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;E&lt;/span&gt; &lt;span class="na"&gt;extends&lt;/span&gt; &lt;span class="na"&gt;React&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ElementType&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"button"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;(&lt;span class="si"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;restProps&lt;/span&gt;
&lt;span class="si"&gt;}&lt;/span&gt;: IButtonProps&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;E&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;) =&amp;gt; &lt;span class="si"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&lt;/span&gt;&lt;span class="dl"&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Element&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;restProps&lt;/span&gt;&lt;span class="si"&gt;}&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="nc"&gt;Element&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="si"&gt;}&lt;/span&gt;;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E pronto!! Agora nosso componente já deve aceitar elemento HTML recebidos pela propriedade &lt;code&gt;as&lt;/code&gt; e adicionar todas as propriedades deste elemento no nosso componente &lt;code&gt;Button&lt;/code&gt; além das nossas propriedades personalizadas.&lt;/p&gt;

&lt;p&gt;Abaixo esta o código completo do componente:&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="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="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;PropsOf&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;
  &lt;span class="nx"&gt;E&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;JSX&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;IntrinsicElements&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;JSXElementConstructor&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSX&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LibraryManagedAttributes&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ComponentPropsWithRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&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;IButton&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;E&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ElementType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ElementType&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;as&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Element&lt;/span&gt;&lt;span class="p"&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;type&lt;/span&gt; &lt;span class="nx"&gt;IButtonProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;E&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ElementType&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;IButton&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;
  &lt;span class="nb"&gt;Omit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PropsOf&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;IButton&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;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;E&lt;/span&gt; &lt;span class="na"&gt;extends&lt;/span&gt; &lt;span class="na"&gt;React&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ElementType&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"button"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;(&lt;span class="si"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;restProps&lt;/span&gt;
&lt;span class="si"&gt;}&lt;/span&gt;: IButtonProps&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;E&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;) =&amp;gt; &lt;span class="si"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&lt;/span&gt;&lt;span class="dl"&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Element&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;restProps&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="si"&gt;}&lt;/span&gt;;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Exemplo em execução
&lt;/h4&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/conditional-types-typescript-0t66yi"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Top demais!! 😻
&lt;/h2&gt;

&lt;p&gt;Chegamos ao fim de mais um post e então, gostou?&lt;/p&gt;

&lt;p&gt;Espero que eu tenho conseguido ajudar um pouquinho você a compreender melhor o Typescript e tirar sua curiosidade de como pode ser feito a propriedade &lt;code&gt;as&lt;/code&gt; que aparece em algumas bibliotecas. Achou que eu falei algo errado? Ficou com dúvidas? Vamos discutir melhor sobre nos comentários.&lt;/p&gt;

&lt;p&gt;See you soon!&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://itnext.io/react-polymorphic-components-with-typescript-f7ce72ea7af2" rel="noopener noreferrer"&gt;React polymorphic components with TypeScript | by Iskander Samatov | ITNEXT&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gist.github.com/kripod/4434e7cecfdecee160026aee49ea6ee8" rel="noopener noreferrer"&gt;Polymorphic &lt;code&gt;as&lt;/code&gt; prop for React components with TypeScript (github.com)&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>gratitude</category>
    </item>
    <item>
      <title>Hook useCallback - Entenda quando utiliza-lo?</title>
      <dc:creator>Guilherme Selair</dc:creator>
      <pubDate>Tue, 18 Oct 2022 01:18:44 +0000</pubDate>
      <link>https://dev.to/guiselair/usecallback-hook-entenda-quando-utiliza-lo-3n3k</link>
      <guid>https://dev.to/guiselair/usecallback-hook-entenda-quando-utiliza-lo-3n3k</guid>
      <description>&lt;p&gt;Salve Salve! 🖖🏻 Voltei depois de muitoooo tempo 😅. &lt;/p&gt;

&lt;p&gt;Dessa vez vim falar um pouco sobre um dos famosos &lt;em&gt;hooks&lt;/em&gt; do &lt;em&gt;React&lt;/em&gt;, &lt;em&gt;useCallback.&lt;/em&gt; Percebo que ele gera muita dúvida em quem esta iniciando em &lt;em&gt;React&lt;/em&gt; e até mesmo desenvolvedores que já atuam com ele.&lt;/p&gt;

&lt;p&gt;A ideia deste post é apresentar um pouco sobre a minha visão deste &lt;em&gt;hook&lt;/em&gt; para quem não conhece e esclarecer onde ele pode ser aplicado assim como aplica-lo na pratica. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Este é o começo de uma série de posts falando um pouco mais sobre a minha visão sobre os &lt;em&gt;hooks&lt;/em&gt; disponibilizados pelo &lt;em&gt;React.&lt;/em&gt;&lt;/em&gt;&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%2F2597dqo7fsqmvd8f7yd8.gif" 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%2F2597dqo7fsqmvd8f7yd8.gif" alt="https://media.giphy.com/media/BYS6j7XxxyvTi/giphy.gif" width="245" height="184"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Nota&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Este post não serve de documentação e não tem como objetivo ser o mais completo possível. Ele representa apenas a minha visão sobre a utilização do useCallback que obtive ao longo do tempo.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;A partir do &lt;em&gt;React 16&lt;/em&gt; foram disponibilizados uma série de &lt;em&gt;hooks&lt;/em&gt; nativos que buscam facilitar o desenvolvimento de componentes funcionais. Desses &lt;em&gt;hooks&lt;/em&gt; falaremos neste post sobre &lt;em&gt;useCallback.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  useCallback
&lt;/h3&gt;

&lt;p&gt;Este &lt;em&gt;hook&lt;/em&gt; recebe dois parâmetros, uma função &lt;em&gt;callback&lt;/em&gt; e um array de dependências. O seu retorno é uma &lt;strong&gt;versão memoizada da função&lt;/strong&gt; &lt;em&gt;callback&lt;/em&gt; recebida como primeiro parâmetro. De forma básica quando me refiro em uma versão memoizada podemos nos referir a uma versão memorizada ou “&lt;em&gt;cacheada”&lt;/em&gt; da função.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⛳ &lt;strong&gt;Obs:&lt;/strong&gt; Aqui vale ressaltar um ponto bem importante, o retorno deste hook é uma versão memoizada da função e não do resultado da função. Isso quer dizer que a função só vai ser executada quando você utiliza-la desta maneira: &lt;strong&gt;minhaFuncao()&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Como este &lt;em&gt;callback&lt;/em&gt; é uma versão memoizada é preciso informar quando essa função deve ser recalculada para que valores atualizados sejam utilizados. É por isso que existe o array de dependências passado como segundo parâmetro para &lt;em&gt;hook&lt;/em&gt;. Os valores passado dentro deste array são o que fazem a função &lt;em&gt;callback&lt;/em&gt; ser recalculada. Normalmente variáveis externas a função de &lt;em&gt;callback&lt;/em&gt; que são utilizadas dentro da função, estarão neste array. Caso você não informe as variáveis que são utilizadas dentro da função, a grandes chances delas estarem com seus valores desatualizados quando a função for disparada.&lt;/p&gt;

&lt;p&gt;Abaixo temos um exemplo da sintaxe deste &lt;em&gt;hook&lt;/em&gt;:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useCallback&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;react&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;handleClick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &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="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;sendMail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;address&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="nx"&gt;address&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="err"&gt;...&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="nx"&gt;handleSubmit&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Enviar email&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;/code&gt;&lt;/pre&gt;

&lt;/div&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%2F1xr6163elnc1rvs2imrq.gif" 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%2F1xr6163elnc1rvs2imrq.gif" alt="https://media.giphy.com/media/L3FInpXg6pGEGXPR0a/giphy.gif" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Beleza, mas quando utilizar?
&lt;/h3&gt;

&lt;p&gt;Essa é uma pergunta super interessante e importante, porque o uso em excesso ou da maneira incorreta ao utilizar o &lt;em&gt;useCallback&lt;/em&gt; pode ser pior que utilizar uma simples função comum.&lt;/p&gt;

&lt;p&gt;Este &lt;em&gt;hook&lt;/em&gt; vem pra nos ajudar a melhorar a performance de nossas aplicações mas ao mesmo tempo se utilizarmos de maneira incorreta, estaremos adicionando mais passos/lógicas em nossas funções. Isso porque antes de retornar uma versão &lt;em&gt;memoizada&lt;/em&gt; da função, o &lt;em&gt;hook&lt;/em&gt; faz uma comparação para saber se ele deve ou não recalcular aquela versão para então retornar a versão atualizada do callback.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⛳ &lt;em&gt;Obs: O React já é uma biblioteca muito rápida e eficiente, então em grande parte dos casos, nem iremos notar essas adições de lógicas em nossa aplicação.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Então voltamos a pergunta, &lt;em&gt;quando devo utilizar este hook?&lt;/em&gt; A resposta é apenas uma: &lt;strong&gt;Quando você precisar manter a igualdade referencial.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Você já deve ter escutado bastante sobre renderizações no universo do &lt;em&gt;React.&lt;/em&gt; Quando essas renderizações ocorrem sejam por conta que o componente pai alterou, uma propriedade alterou ou algum estado foi alterado, em todos esses casos os componentes em questão entram em processo de renderização. Isso quer dizer que pelo menos uma comparação entre o componente anterior a renderização e o mesmo componente com os dados alterados é realizada.&lt;/p&gt;

&lt;p&gt;Nesse processo novos blocos de memória (referências) são utilizados para atualizar variáveis/funções. E aqui entra um grande ponto se você já testou comparações no &lt;em&gt;Javascript.&lt;/em&gt; Pois ao fazer a seguinte comparaçã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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){}&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){}&lt;/span&gt;

&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso retornará &lt;code&gt;false&lt;/code&gt; . Essa comparação apenas será &lt;code&gt;true&lt;/code&gt; se a referência das funções forem a mesma. Como a gente pode ver abaixo:&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%2F415msqjdgnjg3klci7gr.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%2F415msqjdgnjg3klci7gr.png" alt="Shallow Compare functions" width="212" height="208"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Podemos notar que apenas quando atribuímos a variável &lt;code&gt;a&lt;/code&gt; a variável &lt;code&gt;b&lt;/code&gt; que a comparação entre as duas funções deu &lt;code&gt;true&lt;/code&gt;. Ou seja, elas utilizam a mesma referência.&lt;/p&gt;

&lt;p&gt;Ter noção disso é muito importante porque pode evitar que algumas renderizações desnecessárias ocorram. E isso não vale somente para funções mas também para objetos e arrays.&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%2Fthumbs.gfycat.com%2FPaleThunderousGroundhog-max-1mb.gif" 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%2Fthumbs.gfycat.com%2FPaleThunderousGroundhog-max-1mb.gif" alt="https://thumbs.gfycat.com/PaleThunderousGroundhog-max-1mb.gif" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Show me the code! 🤖
&lt;/h3&gt;

&lt;p&gt;Vamos parar de papo e mostrar realmente como você deve utilizar este &lt;em&gt;hook.&lt;/em&gt; Imagine o seguinte cenário, você tem um hook de autenticação e através dele você disponibiliza duas funções signIn e signOut. Essas funções podem ser envolvidas pelo &lt;em&gt;useCallback&lt;/em&gt;, isso porque são funções que serão utilizadas em diversos componentes da aplicação e com isso manter a igualdade referencial dessas funções é importante para que se o nosso hook de autenticação for alterado, todos os componentes que o utilizam também serão re-renderizados.&lt;/p&gt;

&lt;p&gt;Abaixo tem um exemplo do cenário ilustrado:&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%2F1wg3scnbi96y1jercf5p.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%2F1wg3scnbi96y1jercf5p.png" alt="AuthContext" width="800" height="486"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora pense em outro cenário: Resolvemos refatorar nosso código e criamos um novo componente para segmentar melhor a lógica. Porém este novo componente terá que atualizar um estado que vai estar em seu componente pai. Para fazer essa atualização, podemos enviar a função que faz essa atualização do pai para o filho e dentro do filho executaríamos esta função passando como parâmetro o valor desejado. &lt;br&gt;
Este é um uso importante do &lt;em&gt;useCallback&lt;/em&gt; também. *&lt;em&gt;Funções que são passadas do pai pro filho devem estar envolvidas pelo *hook.&lt;/em&gt;&lt;br&gt;
**&lt;br&gt;
Novamente aqui a principal motivação para seu uso é manter a igualdade referencial da função. Para notarmos 100% isso funcionando na prática, vamos ter que utilizar também outro &lt;em&gt;hook&lt;/em&gt; do React, o &lt;em&gt;memo.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Obs: Falaremos mais sobre este hook em outro post&lt;/em&gt; 😀&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Abaixo tem um exemplo do cenário ilustrado:&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%2Fjdkfqf3g6hpxq5tf1308.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%2Fjdkfqf3g6hpxq5tf1308.png" alt="FatherWithoutCallback" width="800" height="596"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O código acima tem como retorno os seguintes consoles ao clicar no botão de &lt;em&gt;counter:&lt;/em&gt;&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%2Fz9yysdlxfzt9r82umivl.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%2Fz9yysdlxfzt9r82umivl.png" alt="FatherAndChildrenUpdated" width="482" height="63"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aqui da pra perceber que o “FILHO” só renderizou porque um estado do componente “PAI” foi alterado porém o “FILHO” não recebe o estado que foi alterado. Então você concorda comigo que ele não precisava ser re-renderizado.&lt;br&gt;
Agora se ajustarmos o cenário acima com os &lt;em&gt;hooks useCallback e memo&lt;/em&gt;, temos o seguinte resultado ao clicar no botã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%2Fpv8g04bstpcx2rt5wlqw.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%2Fpv8g04bstpcx2rt5wlqw.png" alt="FatherUpdated" width="316" height="31"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora o componente “FILHO” só renderizará novamente quando a versão &lt;em&gt;memoizada&lt;/em&gt; da função for atualizada, ou seja, somente quando realmente alguma de suas propriedades alterem. O código com a altera ficou deste jeito:&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%2F6ocntbcku9hc1xsomz19.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%2F6ocntbcku9hc1xsomz19.png" alt="FatherToChildWithCallback" width="800" height="596"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Top demais! 😍
&lt;/h3&gt;

&lt;p&gt;Eu espero ter ajudado você a entender um pouquinho mais sobre este &lt;em&gt;hook,&lt;/em&gt; o que é e quando utilizar. Já passei por essas dúvidas e essas foram as minhas conclusões sobre elas.&lt;/p&gt;

&lt;p&gt;Em breve voltarei com outros posts sobre os demais &lt;em&gt;hooks&lt;/em&gt; que o &lt;em&gt;React&lt;/em&gt; nos dispõem.&lt;/p&gt;

&lt;p&gt;Valeeeeu demais pela leitura! Gostou? Ficou com dúvida? Falei alguma coisa errada? Vamos conversar melhor nos comentários&lt;/p&gt;

&lt;p&gt;See you soon! 🖖🏻&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%2F6okm87nb6qatr7afzvmy.gif" 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%2F6okm87nb6qatr7afzvmy.gif" alt="https://media.giphy.com/media/l1J3CbFgn5o7DGRuE/giphy.gif" width="480" height="309"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://reactjs.org/docs/hooks-reference.html#usecallback" rel="noopener noreferrer"&gt;ReactJS DOC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kentcdodds.com/blog/usememo-and-usecallback" rel="noopener noreferrer"&gt;When to useMemo and useCallback&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>beginners</category>
      <category>hooks</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Como implementar Dynamic Link com Firebase e React Native</title>
      <dc:creator>Guilherme Selair</dc:creator>
      <pubDate>Fri, 27 Aug 2021 02:00:00 +0000</pubDate>
      <link>https://dev.to/guiselair/implementando-link-dinamico-com-react-native-4gb3</link>
      <guid>https://dev.to/guiselair/implementando-link-dinamico-com-react-native-4gb3</guid>
      <description>&lt;p&gt;Fala, clã 😎.&lt;/p&gt;

&lt;p&gt;Garanto que você já se perguntou como ao clicar em um anúncio em redes sociais você era redirecionado para o aplicativo do anunciante. É exatamente isso que vamos implementar no post de hoje! &lt;/p&gt;

&lt;p&gt;Nessa funcionalidade existe, pelo menos, dois casos de uso: Quando o usuário já tens o aplicativo instalado em seu dispositivo e será preciso apenas redireciona-lo para dentro do app. Ou quando o usuário não tens o aplicativos instalado e então será preciso redireciona-lo para a página na loja do aplicativo a ser instalado.&lt;/p&gt;

&lt;p&gt;Este comportamento pode ser construído utilizando o &lt;em&gt;Dynamic Links&lt;/em&gt; disponibilizado pelo &lt;em&gt;Firebase&lt;/em&gt; e serve tanto para dispositivos IOS, Android e WEB.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Neste post abordaremos com mais foco a configuração dessa funcionalidade em dispositivos Android.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Vou mostrar para vocês como é simples e rápido configura-lo! 🔥 Vamos então definir o escopo de nosso exemplo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Escopo
&lt;/h2&gt;

&lt;p&gt;Teremos duas situações:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Redirecionar para o aplicativo&lt;/strong&gt;: Quando o &lt;em&gt;app&lt;/em&gt; estiver instalado, devemos abri-lo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redirecionar para a Play Store&lt;/strong&gt;: Sem o &lt;em&gt;app&lt;/em&gt; instalado, devemos abrir a &lt;em&gt;Play Store&lt;/em&gt;. Como nosso &lt;em&gt;app&lt;/em&gt; não esta disponível nela, abriremos a página do &lt;em&gt;app&lt;/em&gt; da &lt;em&gt;Netflix&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Criando o aplicativo de exemplo 📳
&lt;/h2&gt;

&lt;p&gt;Utilizaremos o aplicativo padrão quando iniciamos um projeto com &lt;em&gt;react-native-cli&lt;/em&gt; apenas para não tomarmos muito tempo deste post. O &lt;em&gt;app&lt;/em&gt; será semelhante a este:&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%2F6ytkv8bxi8spb9kywpwy.jpeg" 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%2F6ytkv8bxi8spb9kywpwy.jpeg" alt="app react native" width="350" height="622"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Configurações no Firebase Console
&lt;/h2&gt;

&lt;p&gt;Com o &lt;em&gt;app&lt;/em&gt; criado, agora é preciso entrar no &lt;em&gt;Firebase console&lt;/em&gt; e criar um novo projeto.&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%2Fzwep719kfs4y56v9sbcp.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%2Fzwep719kfs4y56v9sbcp.png" alt="criando projeto firebase" width="800" height="363"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Logo após o projeto ser criado, vamos adicionar o aplicativo &lt;em&gt;Android&lt;/em&gt; que irá ser utilizado nesta prática.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adicionando um app Android no Firebase
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Não se preocupe com esse monte de informações! Vamos ver ponto a ponto. Então bora lá!&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Etapa 1
&lt;/h3&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%2Fkquvtumklrsamun7ltgb.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%2Fkquvtumklrsamun7ltgb.png" alt="etapa 1 - app" width="800" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Nome do pacote do Android"&lt;/strong&gt;: Este é o nome do seu &lt;em&gt;app android&lt;/em&gt;, como o próprio nome diz. Este nome esta disponível dentro do arquivo &lt;strong&gt;&lt;em&gt;/android/app/build.gradle.&lt;/em&gt;&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Você vai encontrar o nome da sua aplicação em &lt;strong&gt;applicationId.&lt;/strong&gt;&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%2Fwz8aecfc4okmv76jcg6w.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%2Fwz8aecfc4okmv76jcg6w.png" alt="etapa 1 - app - name" width="471" height="183"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Apelido do app"&lt;/strong&gt;: É o nome que você pode dar para seu &lt;em&gt;app&lt;/em&gt; dentro do &lt;em&gt;firebase&lt;/em&gt; e servirá para identicação dele.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Certificação de assinatura de depuração SHA-1"&lt;/strong&gt;: Apesar de ser um campo opcional você precisará preenche-lo mais tarde. Neste campo precisamos inserir a chave SHA-1 de certificação do projeto. Para gerarmos a chave acesse a pasta "&lt;em&gt;android&lt;/em&gt;" dentro de seu projeto no terminal e execute o seguinte comando.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./gradlew signingReport
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A saída deste comando deve ser semelhante a isto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Task :app:signingReport
Variant: debug
Config: debug
Store: ~/.android/debug.keystore
Alias: AndroidDebugKey
MD5: A5:88:41:04:8D:06:71:6D:FE:33:76:87:AC:AD:19:23
SHA1: A7:89:E5:05:C8:17:A1:22:EA:90:6E:A6:EA:A3:D4:8B:3A:30:AB:18
SHA-256: 05:A2:2C:35:EE:F2:51:23:72:4D:72:67:A5:6C:8C:58:22:2A:00:D6:DB:F6:45:D5:C1:82:D2:80:A4:69:A8:FE
Valid &lt;span class="k"&gt;until&lt;/span&gt;: Wednesday, August 10, 2044
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copie a chave SHA-1 gerada e adicione no campo. Logo após você pode processar para a próxima etapa.&lt;/p&gt;

&lt;h3&gt;
  
  
  Etapa 2
&lt;/h3&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%2Fx1z456xtbknzl15blirx.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%2Fx1z456xtbknzl15blirx.png" alt="etapa 2 - app" width="749" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nessa etapa faça o download do arquivo "&lt;em&gt;google-servces.json"&lt;/em&gt; e adicione-o na pasta "/&lt;em&gt;android/app"&lt;/em&gt; de seu projeto.&lt;/p&gt;

&lt;h3&gt;
  
  
  Etapa 3
&lt;/h3&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%2Fpkwlhoj3gi8z1imeb3on.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%2Fpkwlhoj3gi8z1imeb3on.png" alt="etapa 3 - app" width="800" height="556"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nesta etapa siga as instruções apresentadas inserindo os itens em em seus lugares e logo após tudo feito basta avançar para a quarta etapa.&lt;/p&gt;

&lt;h3&gt;
  
  
  Etapa 4
&lt;/h3&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%2Fovakys4ch3mbhoyuxh7t.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%2Fovakys4ch3mbhoyuxh7t.png" alt="etapa 4 - app" width="769" height="293"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Esta é a etapa de conclusão. Já podemos voltar para o console e criarmos o link dinâmico.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configurando o domínio do link dinâmico
&lt;/h2&gt;

&lt;p&gt;Indo até a sessão "&lt;em&gt;Engajamento&lt;/em&gt;", selecionamos a opção "&lt;em&gt;Dynamic Links&lt;/em&gt;".&lt;/p&gt;

&lt;p&gt;A primeira tela será destinada a preencher o domínio que o link ficará registrado. Caso você não tenha um domínio, não se preocupe, basta escrever um domínio de testes único que o &lt;em&gt;firebase&lt;/em&gt; disponibilizará. Semelhante ao que esta abaixo:&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%2Fzug5nmmn476a9p8ttjd3.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%2Fzug5nmmn476a9p8ttjd3.png" alt="escolhendo dominio" width="716" height="458"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Logo após concluirmos a seleção de domínio a próxima tela será semelhante a esta:&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%2Fheyaap8pcf9c1j01k0h3.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%2Fheyaap8pcf9c1j01k0h3.png" alt="dominio concluido" width="800" height="208"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Será nesta página que realizaremos grande parte das configurações necessárias e também onde ficará todas as estatísticas sobre seus links dinâmicos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Criando um link dinâmico
&lt;/h2&gt;

&lt;p&gt;Clicando no botão "Novo link dinâmico" será aberto um modal com algumas configurações:&lt;/p&gt;

&lt;h3&gt;
  
  
  Etapa 1
&lt;/h3&gt;

&lt;p&gt;A primeira etapa para a criação é definir um link "curto" a fim de identificar mais facilmente o link que acabamos de criar.&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%2Fp6ymcd2dpfajcgxuq5eq.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%2Fp6ymcd2dpfajcgxuq5eq.png" alt="etapa 1" width="669" height="318"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Etapa 2
&lt;/h3&gt;

&lt;p&gt;Na segunda etapa, vamos definir qual URL deverá ser aberta caso o link seja acessado através de um computador. Devemos adicionar uma URL e um nome identificador para esta URL para posteriormente conseguirmos mensurar a quantidade de cliques nela. &lt;/p&gt;

&lt;p&gt;Aqui, como exemplo, vou adicionar a URL da &lt;em&gt;Netflix&lt;/em&gt;. &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%2Fhnn5buvzvihh8sjyu94f.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%2Fhnn5buvzvihh8sjyu94f.png" alt="etapa 2" width="658" height="337"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Etapa 3
&lt;/h3&gt;

&lt;p&gt;Na terceira etapa, vamos definir o comportamento do nosso link dinâmico em dispositivos IOS. Temos duas opções, abrir o link em um navegador ou abrir o link em um &lt;em&gt;app&lt;/em&gt; IOS. Caso a seleção "abrir no navegador" for marcada, quando um dispositivo IOS acessar o link dinâmico será aberto a URL definida anteriormente no navegador do dispositivo.&lt;/p&gt;

&lt;p&gt;Para selecionar a opção abrir no app IOS será preciso cadastrar um aplicativo IOS. Nesse exemplo vamos selecionar a opção do navegador.&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%2Fk4uhr1m8vi8pnkdo4b1k.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%2Fk4uhr1m8vi8pnkdo4b1k.png" alt="etapa 3" width="462" height="170"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Etapa 4
&lt;/h3&gt;

&lt;p&gt;A quarta etapa é bem semelhante a anterior porém para dispositivos &lt;em&gt;Android&lt;/em&gt;. Nessa etapa vamos selecionar a opção para abrir no &lt;em&gt;app&lt;/em&gt; Android e selecionarmos o aplicativo que criamos no inicio do post.&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%2Frkua1tcon804rn22wdrl.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%2Frkua1tcon804rn22wdrl.png" alt="etapa 5" width="649" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como o aplicativo que criamos não está na &lt;em&gt;Play Store&lt;/em&gt;, vamos adicionar uma URL personalizada para ser aberta caso no dispositivo não tenha instalado nosso &lt;em&gt;app&lt;/em&gt;. Para este exemplo adicionei o link do aplicativo da &lt;em&gt;Netflix&lt;/em&gt; no Play Store.&lt;/p&gt;

&lt;h3&gt;
  
  
  Etapa 5
&lt;/h3&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%2Frspz7oq33bjaj124rp65.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%2Frspz7oq33bjaj124rp65.png" alt="etapa 5" width="681" height="230"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vamos pular esta etapa porque ela se destina apenas para rastreamento de campanhas e marketing.&lt;/p&gt;

&lt;p&gt;Com isso já podemos concluir a criação de nosso link dinâmico! 🎉🎊 Este é o fluxo de navegação do link.&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%2Fmrje6i9e5qrj8q46vc1q.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%2Fmrje6i9e5qrj8q46vc1q.png" alt="arvore do link" width="779" height="518"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Etapa 6
&lt;/h3&gt;

&lt;p&gt;Depois de finalizada a configuração no &lt;em&gt;Firebase console&lt;/em&gt;, precisamos adicionar o domínio do link dinâmico que acabamos de configurar. Dentro de seu &lt;em&gt;app&lt;/em&gt; vamos editar o seguinte arquivo: &lt;em&gt;android/app/src/main/AndroidManifest.xml,&lt;/em&gt; nele dentro das tag &amp;lt;&lt;em&gt;intent-filter&amp;gt;&lt;/em&gt; adicionamos as seguintes linhas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;data&lt;/span&gt; &lt;span class="na"&gt;android:host=&lt;/span&gt;&lt;span class="s"&gt;"DOMINIO_LINK_DINAMICO"&lt;/span&gt; &lt;span class="na"&gt;android:scheme=&lt;/span&gt;&lt;span class="s"&gt;"http"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;data&lt;/span&gt; &lt;span class="na"&gt;android:host=&lt;/span&gt;&lt;span class="s"&gt;"DOMINIO_LINK_DINAMICO"&lt;/span&gt; &lt;span class="na"&gt;android:scheme=&lt;/span&gt;&lt;span class="s"&gt;"https"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Você deve adicionar o dominio de seu link dinamico sem o protocolo. Você deve inseri-lo da seguinte maneira: &lt;strong&gt;&lt;em&gt;seudominio.page.link&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Resultado 🚀
&lt;/h2&gt;

&lt;p&gt;Após feito todas as configurações necessárias, basta esperar alguns minutinhos e já testar seu link dinâmico. Para te mostrar como tudo isso que a gente fez funciona, fica abaixo os resultados.&lt;/p&gt;

&lt;h3&gt;
  
  
  APP DESINSTALADO
&lt;/h3&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%2F8io92bde77tms9ton1ti.gif" 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%2F8io92bde77tms9ton1ti.gif" alt="APP DESINSTALADO" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vale ressaltar que o aplicativo que deve ser aberto na loja, pode ser alterado pelo &lt;em&gt;Firebase&lt;/em&gt; console.&lt;/p&gt;

&lt;h3&gt;
  
  
  APP INSTALADO
&lt;/h3&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%2Fktez6p7qehmxtikgarqb.gif" 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%2Fktez6p7qehmxtikgarqb.gif" alt="APP INSTALADO" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  FICOU MUITO SHOW!!! 😎😍
&lt;/h2&gt;

&lt;p&gt;Espero ter ajudado você a entender melhor como funcionar essa funcionalidade do &lt;em&gt;Firebase&lt;/em&gt; e a utilizar ela na prática. Esta é uma alternativa simples, rápida e que precisa de muito pouco código para funcionar, o que a torna incrível!&lt;/p&gt;

&lt;p&gt;See you soon! 🤠&lt;/p&gt;

&lt;h2&gt;
  
  
  REFERÊNCIAS
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://medium.com/@c.nwaugha/how-to-implement-firebase-dynamic-links-in-react-native-888a554bd7fa" rel="noopener noreferrer"&gt;https://medium.com/@c.nwaugha/how-to-implement-firebase-dynamic-links-in-react-native-888a554bd7fa&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://rnfirebase.io/dynamic-links/usage#android-setup" rel="noopener noreferrer"&gt;https://rnfirebase.io/dynamic-links/usage#android-setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://firebase.google.com/products/dynamic-links" rel="noopener noreferrer"&gt;https://firebase.google.com/products/dynamic-links&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>firebase</category>
      <category>reactnative</category>
      <category>beginners</category>
      <category>react</category>
    </item>
    <item>
      <title>Criando um Layout Persistente em NextJS</title>
      <dc:creator>Guilherme Selair</dc:creator>
      <pubDate>Sat, 22 May 2021 23:44:33 +0000</pubDate>
      <link>https://dev.to/guiselair/criando-um-layout-persistente-em-nextjs-1g8m</link>
      <guid>https://dev.to/guiselair/criando-um-layout-persistente-em-nextjs-1g8m</guid>
      <description>&lt;p&gt;Como da pra notar pelo outros posts, sempre que tenho que implementar algo novo para mim, eu tento postar aqui para ajudar o máximo de pessoas possível e hoje não é diferente! &lt;/p&gt;

&lt;p&gt;Então pega um ☕ e curte o post.&lt;/p&gt;

&lt;h1&gt;
  
  
  # Introdução
&lt;/h1&gt;

&lt;p&gt;Podemos dizer que temos um layout persistente quando um componente é compartilhado em diversas telas de nossa aplicação sem sofrer re-renderizações pela troca de páginas. De maneira mais clara é quando declaramos apenas uma vez o componente para ser utilizado em parte ou em toda a aplicação. Um exemplo disso é o cabeçalho e o rodapé de um projeto que são normalmente compartilhados em diversas páginas porém declarados um vez.&lt;/p&gt;

&lt;h1&gt;
  
  
  # Explicando o exemplo 🤯
&lt;/h1&gt;

&lt;p&gt;No exemplo que vamos construir aqui, quero além de exibir o cabeçalho em todas as páginas, quero também só que apenas nas páginas que estão dentro da pasta &lt;code&gt;/pages/minha-conta/*&lt;/code&gt; exibam um menu de navegação lateral. &lt;/p&gt;

&lt;p&gt;Abaixo há uma imagem para explicar melhor o que será desenvolvido.&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%2Ffpkb85x9y77d2i6eu20e.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%2Ffpkb85x9y77d2i6eu20e.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  # Ao código! 👨‍💻
&lt;/h1&gt;

&lt;h2&gt;
  
  
  ## Adicionando cabeçalho e entendendo o uso de App
&lt;/h2&gt;

&lt;p&gt;Como estamos usando o nextjs para este exemplo, nosso arquivo &lt;code&gt;_app.js&lt;/code&gt; deve ser parecido com esse:&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pageProps&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;Component&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;pageProps&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;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como você deve saber, toda página que temos em nossa aplicação na hora de sua execução ela será executada como o &lt;code&gt;Component&lt;/code&gt; acima. &lt;/p&gt;

&lt;p&gt;Por exemplo: temos a página &lt;code&gt;meus-dados.js&lt;/code&gt; quando o usuário acessar esta página em seu navegador, o &lt;em&gt;nextjs&lt;/em&gt; "enviará" o componente exportado pela página de &lt;code&gt;meus-dados.js&lt;/code&gt; para o arquivo &lt;code&gt;_app.js&lt;/code&gt; . Neste arquivo obtemos o componente a ser executado e suas propriedades (caso tenha), e em seguida o executamos utilizando &lt;code&gt;&amp;lt;Component /&amp;gt;&lt;/code&gt; .&lt;/p&gt;

&lt;p&gt;Entendido isso então percebemos que conseguimos envolver este &lt;code&gt;Component&lt;/code&gt; com um &lt;em&gt;Fragment Operator&lt;/em&gt; para possibilitar a renderização de qualquer outro componente junto com a página em execução.&lt;/p&gt;

&lt;p&gt;Portanto conseguimos adicionar um componente que &lt;strong&gt;será exibido em todas as páginas&lt;/strong&gt; de nossa aplicação dessa maneira:&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pageProps&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;&amp;gt;&lt;/span&gt; 
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Header&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;Component&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;pageProps&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;/&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;Show! Cabeçalho adicionado ✅ 👏&lt;/p&gt;

&lt;h2&gt;
  
  
  ## Adicionando menu lateral
&lt;/h2&gt;

&lt;p&gt;Para adicionar o menu lateral somente para as páginas que fazem parte da pasta &lt;code&gt;minha-conta&lt;/code&gt; precisamos realizar mais algumas alterações. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A ideia que eu quero aqui é: Declarar apenas uma vez o componente do menu lateral e fazer ele parecer em todas as páginas da pasta &lt;code&gt;minha-conta&lt;/code&gt; .&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Usarei aqui como exemplo as páginas &lt;code&gt;/pages/minha-conta/meus-dados&lt;/code&gt; e &lt;code&gt;/pages/minha-conta/alterar-senha&lt;/code&gt; . &lt;/p&gt;

&lt;p&gt;Abaixo fica mais claro o nosso objetivo:&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%2Fv19yxnkrncn37xujwc56.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%2Fv19yxnkrncn37xujwc56.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Precisamos de um filtro para selecionar em qual tela devemos exibir o menu. Não podemos apenas adicionar o componente junto ao cabeçalho como fizemos acima pois senão o menu seria renderizado em todas as telas.&lt;/p&gt;

&lt;p&gt;Vamos então construir um novo componente que envolverá todas as páginas que precisamos e nele adicionarmos o componente de menu. Vou chamar de MyAccountLayout esse componente que criaremos.&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;SideMenu&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;../_components/SideMenu&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;MyAccountLayout&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SideMenu&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;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;MyAccountLayout&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como o componente acima servirá como um &lt;em&gt;wrapper&lt;/em&gt; precisamos que ele aceite os &lt;code&gt;children&lt;/code&gt; que são todos os componentes envolvidos por ele.&lt;/p&gt;

&lt;p&gt;Agora em todas as páginas que o menu deve aparecer, devemos adicionar uma propriedade no componente a ser exportado. O nome dessa propriedade pode ser qualquer um, eu vou chamar de layout. É nessa propriedade &lt;code&gt;layout&lt;/code&gt; que vamos adicionar o componente &lt;code&gt;MyAccountLayout&lt;/code&gt; que criamos acima.&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;//Página de meus-dados&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;MyAccountLayout&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;../_layout&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;UserData&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="p"&gt;{...}&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;layout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;MyAccountLayout&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;UserData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para finalizar, no arquivo _app.js vamos criar um componente para receber o conteúdo da propriedade &lt;code&gt;layout&lt;/code&gt; caso exista, caso não exista vamos adicionar um &lt;em&gt;Fragment Operator&lt;/em&gt;. Além disso vamos envolver o &lt;code&gt;Component&lt;/code&gt; pelo componente criado.&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pageProps&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;CustomLayout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;layout&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;layout&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Fragment&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;&amp;gt;&lt;/span&gt; 
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Header&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;CustomLayout&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;Component&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;pageProps&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="nc"&gt;CustomLayout&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&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;Com isso já temos o que queríamos! Menu lateral adicionado apenas nas páginas da pasta &lt;code&gt;minha-conta&lt;/code&gt; .&lt;/p&gt;

&lt;p&gt;E o melhor, você consegue fazer qualquer outro layout persistente usando esta mesma técnica, basta criar o componente de seu layout e atribui-lo a propriedade &lt;code&gt;layout&lt;/code&gt; do componente da página. Show né!&lt;/p&gt;

&lt;h1&gt;
  
  
  # Conclusão 😻
&lt;/h1&gt;

&lt;p&gt;Chegamos ao fim de mais um post e então, gostou? &lt;/p&gt;

&lt;p&gt;Sempre busco explicar o máximo que consigo para que todos que leiam entendam o que estamos fazendo e consigam aplicar em seus projetos. &lt;/p&gt;

&lt;p&gt;Sobre a maneira que fizemos o layout persistente, vale salientar que existem inúmeras maneiras de fazer isso, este foi o jeito que mais gostei seguinte as dicas do link nas referências.&lt;/p&gt;

&lt;p&gt;See you soon!&lt;/p&gt;

&lt;h1&gt;
  
  
  # Referências
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://adamwathan.me/2019/10/17/persistent-layout-patterns-in-nextjs/" rel="noopener noreferrer"&gt;Persistent Layout Patterns in Next.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>nextjs</category>
      <category>beginners</category>
      <category>persistentlayout</category>
    </item>
    <item>
      <title>Implementando um scroll infinito em ReactJS</title>
      <dc:creator>Guilherme Selair</dc:creator>
      <pubDate>Sat, 08 May 2021 00:00:09 +0000</pubDate>
      <link>https://dev.to/guiselair/implementando-um-scroll-infinito-95b</link>
      <guid>https://dev.to/guiselair/implementando-um-scroll-infinito-95b</guid>
      <description>&lt;p&gt;Salve clã! 😁 &lt;/p&gt;

&lt;p&gt;Ultimamente tive que adicionar um scroll infinito em uma aplicação e a primeira coisa que veio a cabeça foi procurar uma biblioteca que já tenha implementado isso. Porém me perguntei: Porque não? Porque não implementar esta funcionalidade? e aqui estou 😁.&lt;/p&gt;

&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Infinite scroll é uma funcionalidade que ajuda a melhorar a experiência do usuário quando há muitos itens a serem exibidos. Quando o scroll se aproxima ou chega ao final da lista ou página, automaticamente a função que faz a requisição para buscar mais posts é acionada passando a próxima pagina para a rota, sem nem o usuário ter que seleciona-la. Assim que os novos elementos forem recebidos do backend, eles serão concatenados com os que já existiam na lista.&lt;/p&gt;

&lt;p&gt;Apesar de substituir a paginação no frontend ainda é preciso dela em seu backend pois a procura por mais posts ocorre pelo incremento das páginas.&lt;/p&gt;

&lt;p&gt;Nós conseguimos ver o uso desta estratégia em sites agrupadores de promoção como &lt;a href="https://www.promobit.com.br/" rel="noopener noreferrer"&gt;Promobit&lt;/a&gt; e &lt;a href="https://opaganhei.com.br/" rel="noopener noreferrer"&gt;Opa!Ganhei&lt;/a&gt;. Além de ser muito utilizada também em redes sociais.&lt;/p&gt;

&lt;h1&gt;
  
  
  IntersectionObserver API
&lt;/h1&gt;

&lt;p&gt;Para realizar esta funcionalidade utilizaremos uma API nativa do browser para nos auxiliar a monitorar o scroll na tela, chamada &lt;strong&gt;IntersectionObserver&lt;/strong&gt;. Esta API é uma ótima alternativa para gerenciar elementos que vão entrar e sair de outro elemento ou da janela de exibição (viewport) e para quando isto acontecer disparar uma função de callback. &lt;br&gt;
Esta é ferramenta muito vasta, caso queira dar uma lida mais aprofundada deixarei o link da MDN nas referências.&lt;/p&gt;
&lt;h1&gt;
  
  
  Ao código. 👨‍💻🚀
&lt;/h1&gt;

&lt;p&gt;Utilizarei o projeto desenvolvido durante a NLW 05, para realizar esta funcionalidade.&lt;/p&gt;

&lt;p&gt;Para não perdemos tempo com código que não esta relacionado a este post, abaixo estará parte do código desenvolvido no projeto.&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;allEpisodes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;latestEpisodes&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;IHome&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="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="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;homepage&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;section&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;allEpisodes&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="si"&gt;{&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;lt;&lt;/span&gt;&lt;span class="nt"&gt;tbody&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;allEpisodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;episode&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&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;tr&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;episode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&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;td&lt;/span&gt; &lt;span class="na"&gt;style&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="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;72&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="nc"&gt;Image&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;episode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;thumbnail&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;episode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;objectFit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"cover"&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;td&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;td&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;Link&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`/episodes/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;episode&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="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;a&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;episode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&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;a&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;Link&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;td&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;td&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;episode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;members&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;td&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;td&lt;/span&gt; &lt;span class="na"&gt;style&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="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&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="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;episode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;publishedAt&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;td&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;td&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;episode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;durationAsString&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;td&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;td&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="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&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="nt"&gt;img&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/play-green.svg"&lt;/span&gt; &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Tocar episódio"&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;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;td&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;tr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&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;lt;/&lt;/span&gt;&lt;span class="nt"&gt;tbody&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;table&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;section&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="err"&gt;/&lt;/span&gt;&lt;span class="na"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  )
}

export const getStaticProps: GetStaticProps = async () =&amp;gt; &lt;span class="si"&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;data&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="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;episodes&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;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;_limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;_sort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;published_at&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;_order&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;desc&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;allEpisodes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nx"&gt;latestEpisodes&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="si"&gt;}&lt;/span&gt;;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como estamos em um projeto NextJS, é comum buscar os todos os episódios pelo getStaticProps e o resultado enviarmos para o componente da página. Porém como iremos implementar o infinite scroll, precisamos no inicio buscar somente a primeira página de episódios.&lt;/p&gt;

&lt;p&gt;Portanto precisamos adicionar o query param &lt;code&gt;_page=1&lt;/code&gt; para buscarmos a primeira página de episódios.&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="kd"&gt;const&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;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;episodes&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;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;_page&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;_limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;_sort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;published_at&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;_order&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;desc&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora dentro do componente da página, precisamos armazenar a variável &lt;code&gt;allEpisodes&lt;/code&gt; em um estado, para posteriormente adicionarmos novos episódios a medida com o usuário for descendo a página. Além disso também será necessário criar um estado para armazenar o valor da página atual.&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;allEpisodes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;latestEpisodes&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;IHome&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;episodes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setEpisodes&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;allEpisodes&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;currentPage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCurrentPage&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&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="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;O &lt;strong&gt;IntersectionObserver&lt;/strong&gt; precisa monitorar um ou mais elementos para detectar se ele está ou não dentro do campo de visão da viewport. Para isso então vamos adicionar ao final da lista de podcasts um elemento HTML para ser observado e nele adicionamos uma referência.&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loadMoreRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&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="c1"&gt;//NO FINAL DA LISTA DE PODCASTS&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;loadMoreRef&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Carregando mais episodios...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;A ideia então é: Sempre que o elemento com a referência &lt;em&gt;loadMoreRef&lt;/em&gt; estiver visível precisamos buscar mais episódios, quando não estiver, o usuário não chegou ao final da listagem, portanto nada será feito.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Sintaxe do IntersectionObserver
&lt;/h3&gt;

&lt;p&gt;A sintaxe do IntersectionObserver é a seguinte:&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;observer&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;IntersectionObserver&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="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para declararmos nosso observer (observador) será necessário passar ao construtor uma função callback e alguns parâmetros de configuração. &lt;/p&gt;

&lt;h3&gt;
  
  
  Declarando o observador
&lt;/h3&gt;

&lt;p&gt;Sobre os parâmetros de configuração, você pode ver a descrição completa na MDN da API mas falarei um pouco sobre o &lt;em&gt;threshold&lt;/em&gt; que a porcentagem de exibição do elemento observado. Isso quer dizer que, nosso exemplo, somente quando o nosso elemento HTML &lt;code&gt;p&lt;/code&gt; for exibido 100% é que será disparada a função callback.&lt;/p&gt;

&lt;p&gt;Com o observer declarado será necessário passar nosso elemento que será observado a ele através do método &lt;em&gt;observe.&lt;/em&gt;&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="nf"&gt;useEffect&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;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;root&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="na"&gt;rootMargin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;20px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;threshold&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.0&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;observer&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;IntersectionObserver&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;entities&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;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;entities&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&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;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isIntersecting&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="nf"&gt;setCurrentPage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;old&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;old&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&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="nx"&gt;options&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;loaderRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
      &lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loaderRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&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="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Função callback
&lt;/h3&gt;

&lt;p&gt;Na função callback recebemos como parâmetro todos os elementos observados em formato de array mas como nós só estamos observando um elemento atribuímos o primeiro campo do array ao target.&lt;/p&gt;

&lt;p&gt;Dentro do &lt;em&gt;target&lt;/em&gt; temos a propriedade chamada &lt;strong&gt;isIntersecting&lt;/strong&gt; que indica se o elemento observado fez a transição para um estado de interseção ou fora de um estado de interseção. Com isso conseguimos garantir que o elemento entrou na área visível da tela e precisamos buscar mais episódios. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Nessa parte, eu achei melhor fazer a requisição em outro useEffects sempre que o valor da página sofrer alteração.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&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;handleResquest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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;data&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="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;episodes&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;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;_page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;currentPage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;_limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;_sort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;published_at&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;_order&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;desc&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;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;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&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;Os episodios acabaram&lt;/span&gt;&lt;span class="dl"&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;}&lt;/span&gt;

      &lt;span class="nf"&gt;setEpisodes&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;episodes&lt;/span&gt;&lt;span class="p"&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="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;handleResquest&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="nx"&gt;currentPage&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O useEffect acima é bem parecido com nosso getStaticProps que busca por novos episódios, a diferença é que concatenamos os novos episódios aos já existentes.&lt;/p&gt;

&lt;p&gt;Com isso temos um scroll infinito funcionando 🚀! Vou deixar o código completo abaixo para você dar uma olhada em caso de dúvidas.&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;allEpisodes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;latestEpisodes&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;IHome&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;episodes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setEpisodes&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;allEpisodes&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;currentPage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCurrentPage&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;hasEndingPosts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setHasEndingPosts&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&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;loaderRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&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="nf"&gt;useEffect&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;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;root&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="na"&gt;rootMargin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;20px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;threshold&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.0&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;observer&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;IntersectionObserver&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;entities&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;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;entities&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&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;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isIntersecting&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="nf"&gt;setCurrentPage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;old&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;old&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&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="nx"&gt;options&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;loaderRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
      &lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loaderRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&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="p"&gt;[]);&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleResquest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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;data&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="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;episodes&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;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;_page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;currentPage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;_limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;_sort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;published_at&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;_order&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;desc&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;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;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="nf"&gt;setHasEndingPosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&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;}&lt;/span&gt;

      &lt;span class="nf"&gt;setEpisodes&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;episodes&lt;/span&gt;&lt;span class="p"&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="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;handleResquest&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="nx"&gt;currentPage&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;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;homepage&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;section&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;allEpisodes&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="si"&gt;{&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;lt;&lt;/span&gt;&lt;span class="nt"&gt;tbody&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;episodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;episode&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&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;tr&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;episode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&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;td&lt;/span&gt; &lt;span class="na"&gt;style&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="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;72&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="nc"&gt;Image&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;episode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;thumbnail&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;episode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;objectFit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"cover"&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;td&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;td&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;Link&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`/episodes/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;episode&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="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;a&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;episode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&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;a&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;Link&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;td&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;td&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;episode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;members&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;td&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;td&lt;/span&gt; &lt;span class="na"&gt;style&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="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&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="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;episode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;publishedAt&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;td&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;td&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;episode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;durationAsString&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;td&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;td&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="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&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="nt"&gt;img&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/play-green.svg"&lt;/span&gt; &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Tocar episódio"&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;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;td&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;tr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&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;lt;/&lt;/span&gt;&lt;span class="nt"&gt;tbody&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;table&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;p&lt;/span&gt; &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;loaderRef&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Carregando mais episodios...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&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;section&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="err"&gt;/&lt;/span&gt;&lt;span class="na"&gt;div&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;&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%2Fi4b8fwa3y6l9lfixt9wx.gif" 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%2Fi4b8fwa3y6l9lfixt9wx.gif" alt="Podcastr" width="600" height="274"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;É isso ae! 😁 Vimos como implementar um scroll infinito simples que quase sempre optamos por utilizar uma lib que já implemente isso para a gente 😂😂.&lt;/p&gt;

&lt;p&gt;Espero ter ajudado você a compreender a construção dessa funcionalidade e fico muito feliz por você ter chegado até aqui 🖖🤘. Vale salientar que o aprendizado é constante e sempre haverá o que melhorar. Caso tenha alguma dúvida ou dicas de melhorias, fique a vontade para entrar em contato comigo.&lt;/p&gt;

&lt;p&gt;See you soon!&lt;/p&gt;

&lt;h4&gt;
  
  
  Referências!
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API" rel="noopener noreferrer"&gt;MDN IntersectionObserver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/hunterjsbit/react-infinite-scroll-in-few-lines-588f"&gt;React infinite scroll in few lines&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>nextjs</category>
      <category>react</category>
      <category>infinitescroll</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Utilizando variáveis de ambiente no ReactJS</title>
      <dc:creator>Guilherme Selair</dc:creator>
      <pubDate>Sun, 13 Dec 2020 20:53:24 +0000</pubDate>
      <link>https://dev.to/guiselair/utilizando-variaveis-de-ambiente-com-create-react-app-5ckc</link>
      <guid>https://dev.to/guiselair/utilizando-variaveis-de-ambiente-com-create-react-app-5ckc</guid>
      <description>&lt;p&gt;Fala clã! Tudo tranquilo? Depois de um tempo sem dar as caras, eu voltei mas sem enrolação vamos ao tema de hoje! &lt;/p&gt;

&lt;p&gt;Hoje pretendo falar um pouco sobre variáveis de ambiente e como elas me ajudaram muito durante esta semana.&lt;/p&gt;

&lt;h2&gt;
  
  
  Porque utilizar variáveis de ambiente em um projeto?
&lt;/h2&gt;

&lt;p&gt;Basicamente, estas variáveis podem guardar informações que não podem serem vazadas para o mundo externo, por exemplo, &lt;strong&gt;chaves e senhas de APIs ou banco de dados&lt;/strong&gt;, como também configurações mais especificas deles também.&lt;/p&gt;

&lt;p&gt;Mas ao meu ver, o mais legal é poder definir diferentes conteúdos das variáveis dependendo do ambiente em que você se encontra, por exemplo, ambientes de desenvolvimento, testes e produção.&lt;/p&gt;

&lt;p&gt;Para exemplificar melhor, digamos que temos o seguinte cenário:&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;//REQUISIÇÃO PARA ALGUMA COISA&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="nx"&gt;LINK&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste cenário estamos requisitando a alguma API local certos dados e esperamos seu retorno. Caso tenhamos diferentes ambientes que executam este trecho de código, o LINK ali usado pode ser diferentes entre eles e como corrigimos isso? &lt;/p&gt;

&lt;p&gt;Assim?&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;//REQUISIÇÃO PARA ALGUMA COISA&lt;/span&gt;
&lt;span class="c1"&gt;//const response = await fetch(LINK_PARA_TESTE);&lt;/span&gt;
&lt;span class="c1"&gt;//const response = await fetch(LINK_PARA_DESENVOLVIMENTO);&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="nx"&gt;LINK_PARA_PRODUCAO&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A resposta é &lt;strong&gt;NÃO&lt;/strong&gt;. Ao invés de ficarmos comentando linhas que não devem serem usadas podemos adicionar uma variável de ambiente para nos ajudar nessa ocasião e não ter mais que comentar as linhas incorretas. Nesta variável irá conter o link correto para o ambiente em execução. O processo todo ficará automático dependendo assim do ambiente em execução. O ambiente correto ficaria semelhante a este:&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;//REQUISIÇÃO PARA ALGUMA COISA&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="nx"&gt;VARIAVEL_DE_AMBIENTE_PARA_O_AMBIENTE_EM_EXECUCAO&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Utilizando variáveis de ambiente no ReactJS
&lt;/h2&gt;

&lt;p&gt;Para esta demonstração vamos utilizar um projeto ReactJS criado com o &lt;em&gt;create-react-app&lt;/em&gt;, então todas as configurações abaixo são aplicadas para este cenário.&lt;/p&gt;

&lt;p&gt;Antes de começarmos tenho uma coisinha a comentar que é muito importante:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;É recomendado que TODA variável de ambiente declarada comece com &lt;strong&gt;REACT_APP_&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Definindo variáveis
&lt;/h2&gt;

&lt;p&gt;Para definir nossas variáveis de ambiente precisamos criar um arquivo para agrupar todas elas. Este arquivo deve ser criado na raiz de seu projeto &lt;em&gt;react&lt;/em&gt; e deve se chamar .env .&lt;/p&gt;

&lt;p&gt;Você vai declarar suas variáveis da seguinte maneira:&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="nx"&gt;REACT_APP_NOME_DA_VARIAVEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;conteudo&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;variavel&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A tipagem de todas as variáveis declaradas são strings. Caso você declare uma variável que tenha o valor false (boolean) quando a sua aplicação precisar dela o valor passado será "false" (string). &lt;/p&gt;

&lt;h2&gt;
  
  
  Utilizando variáveis de ambiente
&lt;/h2&gt;

&lt;p&gt;Para acessar suas variáveis de ambiente utilizamos &lt;em&gt;process.env.NOME_DA_VARIAVEL.&lt;/em&gt; Por padrão sempre terá definida uma variável interna NODE_ENV, está variável é quem diz em que ambiente você está trabalhando e ela não pode ser alterada.&lt;/p&gt;

&lt;p&gt;Em process.env.NODE_ENV podemos ter os valores: test | production | development. Estes valores estão ligados aos comandos de execução da aplicação:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;yarn start → development&lt;/li&gt;
&lt;li&gt;yarn test → test&lt;/li&gt;
&lt;li&gt;yarn build → production&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Esta variável é utilizada para tomar decisões dependendo o ambiente em execução. Por exemplo, desabilitar o uso do analytics em ambiente de testes ou desenvolvimento.&lt;/p&gt;

&lt;p&gt;Portanto podemos voltar ao exemplo passado e modifica-lo. Digamos que declaramos uma variável  ambiente chamada &lt;strong&gt;REACT_APP_LINK_API&lt;/strong&gt; contendo a URL da API. Utilizaremos ela da seguinte maneira:&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;//REQUISIÇÃO PARA ALGUMA COISA&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="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;REACT_APP_LINK_API&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste ponto pode surgir a dúvida: Mas eu tenho apenas um arquivo .env com a variável &lt;strong&gt;REACT_APP_LINK_API&lt;/strong&gt; que contem apenas um valor, como adiciono as outras URLs?&lt;/p&gt;

&lt;p&gt;É nesse ponto que teremos que diferenciar os ambientes com arquivos .env diferentes&lt;/p&gt;

&lt;h2&gt;
  
  
  Diferenciando ambientes
&lt;/h2&gt;

&lt;p&gt;Digamos que temos dois ambientes: desenvolvimento e produção. Ambos utilizam a mesma variável porém com valores diferentes. Teremos então que ter dois arquivos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;.env.production: Irá conter valores das variaveis para produção&lt;/li&gt;
&lt;li&gt;.env: Irá conter valores das variaveis para desenvolvimento&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;É recomendado que ambos tenham as mesmas variáveis para evitar futuros erros. Ou seja, teremos:&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;//.env&lt;/span&gt;
&lt;span class="nx"&gt;REACT_APP_LINK_API&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//localhost:3333&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;//.env.production&lt;/span&gt;
&lt;span class="nx"&gt;REACT_APP_LINK_API&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//minha-api.com.br&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Show né? 🤔🤔🤔&lt;/p&gt;

&lt;p&gt;Agora para ver tudo funcionando temos que instalar um carinha chamado &lt;strong&gt;&lt;em&gt;env-cmd&lt;/em&gt;&lt;/strong&gt; como dependência de desenvolvimento e adicionar a seguinte configuração para cada script de execução do &lt;em&gt;package.json&lt;/em&gt;.&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scripts&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;start&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;env-cmd -f ./.env react-scripts start&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;build&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;env-cmd -f ./.env.production react-scripts build&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;test&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;react-scripts test&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;eject&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;react-scripts eject&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A partir deste momento, quando executado &lt;em&gt;yarn start&lt;/em&gt; as variaveis ambiente de desenvolvimento serão carregadas e quando executado &lt;em&gt;yarn build&lt;/em&gt; as variaveis de produção serão carregadas.&lt;/p&gt;

&lt;p&gt;TOOOOP! 😍 &lt;/p&gt;

&lt;p&gt;Agora esta tudo automatico, não precisamos mais comentar aquela linha de requisição para a API com a URL de produção quando estamos em desenvolvimento!!!&lt;/p&gt;

&lt;p&gt;Curtiu esse post? Ficaria muito feliz em receber o feedback de vocês! Pode deixar um comentario se curtiu ou não curtiu. Dicas construitivas são super bem-vindas! Espero que eu tenha conseguido ajudar alguem. Até o próximo!! 🥰&lt;/p&gt;

&lt;h3&gt;
  
  
  REFERENCIAS:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://create-react-app.dev/docs/adding-custom-environment-variables/" rel="noopener noreferrer"&gt;https://create-react-app.dev/docs/adding-custom-environment-variables/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Deploy ReactJS em Servidor Apache</title>
      <dc:creator>Guilherme Selair</dc:creator>
      <pubDate>Sun, 02 Aug 2020 00:01:08 +0000</pubDate>
      <link>https://dev.to/guiselair/deploy-reactjs-em-servidor-apache-4gb0</link>
      <guid>https://dev.to/guiselair/deploy-reactjs-em-servidor-apache-4gb0</guid>
      <description>&lt;p&gt;Salve clã! 😁 &lt;/p&gt;

&lt;p&gt;Este post é como resolvi um problema que tive essa semanal quando tive que fazer o deploy de um projeto ReactJS em um servidor Apache. Acho interessante compartilhar com vocês.&lt;/p&gt;

&lt;p&gt;Sem mais enrolação! 🚀&lt;/p&gt;

&lt;p&gt;Todo o processo de criação e produção de seu projeto continua o mesmo. Entretanto temos alguns pontos pra ressaltar.&lt;/p&gt;

&lt;p&gt;Devemos adicionar no arquivo .htaccess, que deve ficar no diretório que contem o arquivo index.html, o seguinte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Outro ponto importante, e foi onde eu empaquei é 🤔, caso seu projeto fique como um subdominio do site como: &lt;a href="https://myapp.com/the-app" rel="noopener noreferrer"&gt;https://myapp.com/the-app&lt;/a&gt;, você deve especificar isso no seu Router dentro do seu projeto. &lt;br&gt;
Esta informação deverá estar presente no BrowserRouter na opção basename="/the-app", caso contrario o React interpretará que seu projeto estará na raiz do domínio.&lt;/p&gt;

&lt;p&gt;Abaixo temos um exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import { BrowserRouter, Switch, Route } from "react-router-dom";

import Home from "./pages/home";
import Support from "./pages/support";

export default function Routes(){
    return(
        &amp;lt;BrowserRouter basename="/the-app"&amp;gt;
            &amp;lt;Switch&amp;gt;
                &amp;lt;Route path="/" exact component={Home} /&amp;gt;               
                &amp;lt;Route path="/support" component={Support} /&amp;gt;
            &amp;lt;/Switch&amp;gt;
        &amp;lt;/BrowserRouter&amp;gt;
    );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Além disso devemos também adicionar no arquivo package.json a tag homepage com a url completa que seu projeto estará hospedado. Ex: &lt;a href="https://myapp.com/the-app%C2%A0" rel="noopener noreferrer"&gt;https://myapp.com/the-app &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Não mencionei porém todos já devem estar cientes que depois de todas as alterações feitas, devemos executar o script &lt;strong&gt;build&lt;/strong&gt; para a criação de uma versão otimizada pronta para ser posta em produção. Devemos mover apenas os arquivos que estarão dentro da pasta build para o servidor Apache, não se esqueça disso! 😅&lt;/p&gt;

&lt;p&gt;Este pequeno detalhe de adicionar o basename no BrowserRouter me custou algumas horas de pesquisa, espero que eu tenha te ajudado. 🥰&lt;/p&gt;

&lt;p&gt;Para mais veja meu &lt;a href="https://github.com/GuiSelair" rel="noopener noreferrer"&gt;Github&lt;/a&gt;. 😎&lt;/p&gt;

</description>
      <category>react</category>
      <category>deploy</category>
      <category>apache</category>
      <category>dev</category>
    </item>
  </channel>
</rss>
