<?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>Forem: Dev Maiqui 🇧🇷</title>
    <description>The latest articles on Forem by Dev Maiqui 🇧🇷 (@maiquitome).</description>
    <link>https://forem.com/maiquitome</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%2F605701%2Fcd24d799-3bdf-4c77-be73-bf12006b7300.jpg</url>
      <title>Forem: Dev Maiqui 🇧🇷</title>
      <link>https://forem.com/maiquitome</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/maiquitome"/>
    <language>en</language>
    <item>
      <title>⚛️⏳Parte 4: Criando um Timer com Histórico em React</title>
      <dc:creator>Dev Maiqui 🇧🇷</dc:creator>
      <pubDate>Wed, 12 Mar 2025 11:37:53 +0000</pubDate>
      <link>https://forem.com/maiquitome/parte-4-criando-um-timer-com-historico-em-react-5gmd</link>
      <guid>https://forem.com/maiquitome/parte-4-criando-um-timer-com-historico-em-react-5gmd</guid>
      <description>&lt;p&gt;Esta é a quarta parte do projeto que construí na formação React da &lt;a href="https://app.rocketseat.com.br/cart/rocketseat-one?referral=maiquitome&amp;amp;coupon=indicamgm&amp;amp;utm_source=platform&amp;amp;utm_medium=organic&amp;amp;utm_campaign=venda&amp;amp;utm_term=mgm&amp;amp;utm_content=indication-lp_one" rel="noopener noreferrer"&gt;Rocketseat&lt;/a&gt;, um projeto de duas páginas/telas, onde uma tela contém o timer, e a outra tela contém o histórico dos ciclos realizados.&lt;/p&gt;

&lt;p&gt;Nesta quarta parte do projeto vamos focar nas funcionalidades da aplicação.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Caso queira adquirir os cursos da Rocketseat com o meu cupom de desconto &lt;a href="https://app.rocketseat.com.br/cart/rocketseat-one?referral=maiquitome&amp;amp;coupon=indicamgm&amp;amp;utm_source=platform&amp;amp;utm_medium=organic&amp;amp;utm_campaign=venda&amp;amp;utm_term=mgm&amp;amp;utm_content=indication-lp_one" rel="noopener noreferrer"&gt;Acesse esse link&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links úteis:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer" rel="noopener noreferrer"&gt;Meu repositório do projeto&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/rocketseat-education/02-ignite-timer" rel="noopener noreferrer"&gt;Repositório oficial do Rocketseat&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.figma.com/community/file/1127351821076435124/ignite-timer" rel="noopener noreferrer"&gt;Figma do projeto feito pela Rocketseat&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Capítulos:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
1 - Iniciando novo ciclo

&lt;ul&gt;
&lt;li&gt;1.1 - Closures no React&lt;/li&gt;
&lt;li&gt;1.2 - Apenas um ciclo ativo&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

2 - Criando countdown

&lt;ul&gt;
&lt;li&gt;2.1 - Separando minutos e segundos&lt;/li&gt;
&lt;li&gt;2.2 - Instalando date-fns&lt;/li&gt;
&lt;li&gt;2.3 - Reduzindo countdown com &lt;code&gt;useEffect&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;2.4 - Usando &lt;code&gt;return&lt;/code&gt; dentro do &lt;code&gt;useEffect&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;4 - Timer no título do navegador&lt;/li&gt;

&lt;li&gt;5 - Interrompendo o ciclo&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  1 - Iniciando novo ciclo &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Até agora o que nós temos é uma função chamada &lt;code&gt;handleCreateNewCycle&lt;/code&gt; fazendo um &lt;code&gt;console.log&lt;/code&gt; dos dados:&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%2Fggny6vwsz27krhy6ar32.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%2Fggny6vwsz27krhy6ar32.png" alt="handleCreateNewCycle com apenas  raw `console.log(data)` endraw  e  raw `reset()` endraw " width="800" height="574"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mas, na verdade, queremos que essa função inicie um novo ciclo, queremos que a aplicação tenha um ciclo ativo. &lt;/p&gt;

&lt;p&gt;E, para refletir isso na interface, que um novo ciclo iniciou, precisamos ter um estado, que é a única forma de armazenar alguma informação no componente que vá fazer com que a interface reaja a essa informação, ou seja, que a interface mude.&lt;/p&gt;

&lt;p&gt;Como vamos ter uma página de histórico dos ciclos, precisamos de uma lista, e precisamos que cada ciclo tenha um identificador.&lt;/p&gt;

&lt;p&gt;Então, vamos criar um estado e uma interface no arquivo &lt;code&gt;src/pages/Home/index.tsx&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Cycle&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;minutesAmount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&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;cycles&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCycles&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Cycle&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;e vamos setar o novo ciclo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleCreateNewCycle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NewCycleFormData&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;newCycle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Cycle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;getTime&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt; &lt;span class="c1"&gt;// retorna em milissegundos&lt;/span&gt;
    &lt;span class="na"&gt;task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;minutesAmount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;minutesAmount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="c1"&gt;// [...cycles, newCycle] está criando uma nova lista, seguindo a recomendação de imutabilidade&lt;/span&gt;
  &lt;span class="nf"&gt;setCycles&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;cycles&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newCycle&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="nf"&gt;reset&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;no fim temos esse código adicionado:&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%2Ffo4ae5t60pmk1nypcgck.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%2Ffo4ae5t60pmk1nypcgck.png" alt="código com estado, interface e setCycles sendo usado" width="800" height="684"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1.1 - Closures no React &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Precisamos fazer uma pequena correção no código abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;setCycles&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;cycles&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newCycle&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Precisamos usar uma função para pegar sempre o estado atual. Isso é chamado de &lt;a href="https://www.updatesemwhere.com.br/por-que-as-closures-sao-tao-importantes-em-frameworks-como-o-react/" rel="noopener noreferrer"&gt;Closure&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;setCycles&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newCycle&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora o &lt;code&gt;state&lt;/code&gt; sempre trará a &lt;code&gt;lista de ciclos&lt;/code&gt; &lt;u&gt;mais recente&lt;/u&gt; antes da gente incluir o novo ciclo. Após a alteração, o &lt;code&gt;state&lt;/code&gt; atual terá o nosso novo ciclo. &lt;/p&gt;

&lt;h3&gt;
  
  
  1.2 - Apenas um ciclo ativo &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Temos a página com a lista de ciclos, mas, apenas um ciclo estará ativo, apenas um ciclo terá a condição &lt;code&gt;Em andamento&lt;/code&gt;.&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%2F3cs57u7glpoezwzhvjnx.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%2F3cs57u7glpoezwzhvjnx.png" alt="Mostrando a lista de ciclos com diferentes status, mas apenas um com status  raw `em andamento` endraw " width="800" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E podemos pensar em duas formas de fazer isso. Uma delas seria colocando &lt;code&gt;isActive&lt;/code&gt; no &lt;code&gt;Cycle&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Cycle&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;minutesAmount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;isActive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mas qual o problema de fazer assim?&lt;/p&gt;

&lt;p&gt;O problema é quando eu setar um novo ciclo como ativo, eu vou ter que percorrer todos os ciclos e verificar qual estava ativo antes para setar como inativo. Então toda vez que a gente for setar um ciclo como ativo, vamos ter que fazer duas operações.&lt;/p&gt;

&lt;p&gt;Existe uma alternativa melhor, que é manter um estado com o ID do ciclo ativo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;activeCycleId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setActiveCycleId&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quando a aplicação inicializa, não terá nenhum ciclo ativo, então o &lt;code&gt;activeCycleId&lt;/code&gt; começa com &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Precisamos agora setar o &lt;code&gt;activeCycleId&lt;/code&gt; quando um novo ciclo for criado:&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%2Fyis1cgrzosgdyhl8vipa.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%2Fyis1cgrzosgdyhl8vipa.png" alt="adicionando  raw `setActiveCycleId(id)` endraw " width="800" height="528"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E percorrer os ciclos para encontrar qual ciclo possui o ID do ciclo ativo:&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%2F8o1irbd36pr929706q01.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%2F8o1irbd36pr929706q01.png" alt="adicionando  raw `cycles.find()` endraw " width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Quando abrir a aplicação pela primeira vez, o &lt;code&gt;console.log(activeCycle)&lt;/code&gt; mostrará &lt;code&gt;undefined&lt;/code&gt;, pois não há um ciclo ativo.&lt;/p&gt;

&lt;p&gt;Após iniciar um novo ciclo clicando no botão &lt;code&gt;▶️ Começar&lt;/code&gt;, podemos ver os dados do ciclo ativo no &lt;code&gt;console&lt;/code&gt;:&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%2Fakckep6vaxccpux08yt4.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%2Fakckep6vaxccpux08yt4.png" alt="ciclo ativo no console" width="707" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OBS: Toda vez que colocamos um &lt;code&gt;console.log&lt;/code&gt; no React, acaba que aparece duas vezes o mesmo resultado no &lt;code&gt;console&lt;/code&gt;. Isso acontece apenas em desenvolvimento e tem relação com o &lt;code&gt;&amp;lt;React.StrictMode&amp;gt;&lt;/code&gt; no arquivo &lt;code&gt;main.tsx&lt;/code&gt;. Isso acontece para o React conseguir detectar alguns tipos de bugs.&lt;/p&gt;

&lt;p&gt;commit: &lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/b7b6818e3492623627a079f172ecf23f6f39d115" rel="noopener noreferrer"&gt;feat: ✨ add newCycle and setActiveCycleId&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2 - Criando countdown &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Nesta parte, quando o ciclo ativo iniciar vamos fazer com que o timer vá reduzindo.&lt;/p&gt;

&lt;p&gt;No arquivo &lt;code&gt;src/pages/Home/index.tsx&lt;/code&gt; dentro da função &lt;code&gt;Home&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;O usuário informa em minutos, mas o timer irá reduzir em segundos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;totalSeconds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;activeCycle&lt;/span&gt; 
  &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;activeCycle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;minutesAmount&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para transformar minutos em segundos, precisamos multiplicar por 60.&lt;/p&gt;

&lt;p&gt;Como o timer irá reduzir a cada um segundo, precisamos de um estado que irá guardar a quantidade de segundos que já se passaram desde que o ciclo ativo iniciou:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;amountSecondsPassed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setAmountSecondsPassed&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;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assim podemos calcular &lt;code&gt;totalSeconds&lt;/code&gt; menos &lt;code&gt;amountSecondsPassed&lt;/code&gt; para mostrar o tempo que já passou na tela. Existem várias estratégias, mas vamos usar essa.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;currentSeconds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;activeCycle&lt;/span&gt;
  &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;totalSeconds&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;amountSecondsPassed&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.1 - Separando minutos e segundos &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Precisamos calcular e separar &lt;code&gt;currentSeconds&lt;/code&gt; em minutos e segundos para mostrar em tela.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;minutesAmount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentSeconds&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;padStart&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0&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;secondsAmount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;currentSeconds&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;padStart&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Entendendo esse cálculo:&lt;/p&gt;

&lt;p&gt;Para transformar segundos em minutos, precisamos dividir por 60.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;25 minutos * 60 = 1500 segundos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1500 segundos / 60 = 25 minutos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;se tiver passado 1 segundo, ao invés de 1500 segundos, teremos 1499 segundos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1499 segundos / 60 = 24,9833333333 minutos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;24,9833333333&lt;/code&gt; por ser um número quebrado não podemos mostrar assim em tela.&lt;/p&gt;

&lt;p&gt;Quantos minutos cheios nós temos em &lt;code&gt;1499 segundos&lt;/code&gt; tirando os quebrados????&lt;/p&gt;

&lt;p&gt;Temos 24 minutos! O outro minuto (0,9833333333) falta 1 segundo.&lt;/p&gt;

&lt;p&gt;Então podemos sempre arredondar essa divisão para baixo usando &lt;code&gt;Math.floor&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;E para pegar os segundos, usamos o operador de resto (Operador Mod) &lt;code&gt;%&lt;/code&gt; que pega o resto da divisão:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1499 segundos % 60 = 59 segundos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E esse &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart" rel="noopener noreferrer"&gt;padStart&lt;/a&gt; serve para quê???&lt;/p&gt;

&lt;p&gt;O método &lt;code&gt;padStart()&lt;/code&gt; preenche a string com outra string (várias vezes, se necessário) até que a string resultante atinja o comprimento fornecido. O preenchimento é aplicado do início dessa string.&lt;/p&gt;

&lt;p&gt;Quando um número for abaixo de 10, exemplo &lt;code&gt;9&lt;/code&gt;, quebraria o layout, mas com &lt;code&gt;padStart&lt;/code&gt; garantimos que o &lt;code&gt;9&lt;/code&gt; se torne &lt;code&gt;09&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Só falta agora mostrar em tela:&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CountdownContainer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;minutesAmount&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="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&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;minutesAmount&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="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Separator&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;Separator&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;secondsAmount&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="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&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;secondsAmount&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="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;CountdownContainer&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;commit: &lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/636bc3a503dece46fdf65812a8d7b5ea2dda052b" rel="noopener noreferrer"&gt;feat: ✨ add countdown&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2.2 - Instalando date-fns &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Daqui a pouco precisaremos usar a função &lt;code&gt;differenceInSeconds&lt;/code&gt; do pacote &lt;a href="https://www.npmjs.com/package/date-fns" rel="noopener noreferrer"&gt;date-fns&lt;/a&gt;, por isso já vamos fazer a instalação dele:&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="nv"&gt;$ &lt;/span&gt;npm i date-fns
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;commit: &lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/fa2e76f5762cdc6ec95ef499362f2fd344312aaf" rel="noopener noreferrer"&gt;chore: ➕ add date lib &lt;code&gt;$ npm i date-fns&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2.3 - Reduzindo countdown com &lt;code&gt;useEffect&lt;/code&gt; &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Existe o método &lt;a href="https://www.w3schools.com/jsref/met_win_setinterval.asp" rel="noopener noreferrer"&gt;setInterval&lt;/a&gt; que possibilita chamar uma função a cada um segundo, ou o tempo que você desejar. Mas esse tempo no navegador não é preciso, é apenas uma estimativa, ou seja, se você setar o tempo de 1 segundo, não quer dizer que sempre será 1 segundo exato. Essa estimativa de tempo leva em consideração desempenho da máquina, aba do navegador em segundo plano, entre outras coisas.&lt;/p&gt;

&lt;p&gt;Então não podemos nos basear no tempo do &lt;code&gt;setInterval&lt;/code&gt; para reduzir o contador, pois pode ser que o timer não fique correto!&lt;/p&gt;

&lt;p&gt;Por isso, vamos gravar o exato momento em que o ciclo ativo iniciou, adicionando &lt;code&gt;startDate&lt;/code&gt; ao &lt;code&gt;Cycle&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newCycle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Cycle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;getTime&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
  &lt;span class="na"&gt;task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;minutesAmount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;minutesAmount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;startDate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="c1"&gt;// Date() grava data e horário&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Usando &lt;code&gt;useEffect&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Para reduzir o countdown vamos utilizar o &lt;code&gt;setInterval&lt;/code&gt; dentro de um hook chamado &lt;code&gt;useEffect&lt;/code&gt;. Se você não tem conhecimento sobre esse hook, deixarei uma sugestão de vídeo explicando sobre: &lt;a href="https://www.youtube.com/watch?v=cIbZxwwf3Qo" rel="noopener noreferrer"&gt;Aprenda useEffect de uma vez por todas 🔥&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como visto no texto mais acima, existe um jeito onde o timer não ficará 100% certo, vamos ver a forma &lt;u&gt;errada&lt;/u&gt; de usar o &lt;code&gt;setInterval&lt;/code&gt; nesse caso:&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%2Fkaznvedtv0ok91yyxqt8.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%2Fkaznvedtv0ok91yyxqt8.png" alt="forma errada de usar o setInterval" width="800" height="325"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pra nos ajudar a fazer da forma correta, vamos importar &lt;code&gt;differenceInSeconds&lt;/code&gt; do pacote &lt;code&gt;date-fns&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;differenceInSeconds&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;date-fns&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;differenceInSeconds&lt;/code&gt; calcula a diferença de duas datas em segundos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;activeCycle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setAmountSecondsPassed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nf"&gt;differenceInSeconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nx"&gt;activeCycle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startDate&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="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;activeCycle&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;activeCycle&lt;/code&gt; entre colchetes (&lt;code&gt;[activeCycle]&lt;/code&gt;) significa que toda vez que &lt;code&gt;activeCycle&lt;/code&gt; mudar, o código dentro do &lt;code&gt;useEffect&lt;/code&gt; será acionado.&lt;/p&gt;

&lt;p&gt;O countdown está reduzindo, mas ainda existem bugs que vamos precisar corrigir ao longo do desenvolvimento.&lt;/p&gt;

&lt;p&gt;commit: &lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/636bc3a503dece46fdf65812a8d7b5ea2dda052b" rel="noopener noreferrer"&gt;feat: ✨ add countdown&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2.4 - Usando &lt;code&gt;return&lt;/code&gt; dentro do &lt;code&gt;useEffect&lt;/code&gt; &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Existe um bug no nosso contador. Podemos perceber que após um ciclo de 10 minutos ter iniciado, ao tentar iniciar um novo ciclo de 20 minutos, por exemplo, o timer não começará nos 20 minutos.&lt;/p&gt;

&lt;h4&gt;
  
  
  Etapas para solucionar o Bug:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;O &lt;code&gt;useEffect&lt;/code&gt; será acionado toda vez que um novo ciclo iniciar, ou seja, quando a variável &lt;code&gt;activeCycle&lt;/code&gt; mudar.&lt;/li&gt;
&lt;li&gt;O que está acontecendo é que quando o &lt;code&gt;useEffect&lt;/code&gt; é chamado, um novo &lt;code&gt;setInterval&lt;/code&gt; está sendo criado, ou seja, não estamos usando sempre o mesmo &lt;code&gt;setInterval&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Precisamos então reiniciar/resetar o &lt;code&gt;setInterval&lt;/code&gt; quando um novo ciclo iniciar, ou seja, quando o &lt;code&gt;useEffect&lt;/code&gt; for chamado novamente.&lt;/li&gt;
&lt;li&gt;Para resetar precisamos usar a função &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/clearInterval" rel="noopener noreferrer"&gt;clearInterval()&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;E para usar a função &lt;code&gt;clearInterval&lt;/code&gt; no momento certo, ou seja, quando o &lt;code&gt;useEffect&lt;/code&gt; for chamado novamente, precisamos usar o &lt;code&gt;return&lt;/code&gt; de dentro do &lt;code&gt;useEffect&lt;/code&gt;, mas também de dentro da condição &lt;code&gt;if&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&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;let&lt;/span&gt; &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;activeCycle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;interval&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setAmountSecondsPassed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nf"&gt;differenceInSeconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nx"&gt;activeCycle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startDate&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="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;clearInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;interval&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="nx"&gt;activeCycle&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Resumindo, o &lt;code&gt;return&lt;/code&gt; dentro do &lt;code&gt;useEffect&lt;/code&gt; não será executado na primeira vez que o &lt;code&gt;useEffect&lt;/code&gt; for chamado, o &lt;code&gt;return&lt;/code&gt; será executado nas próximas vezes que o &lt;code&gt;useEffect&lt;/code&gt; for chamado.&lt;/p&gt;

&lt;p&gt;E para finalizar a correção do bug, precisamos resetar o valor &lt;code&gt;amountSecondsPassed&lt;/code&gt;, usando &lt;code&gt;setAmountSecondsPassed(0);&lt;/code&gt; dentro da função &lt;code&gt;handleCreateNewCycle&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleCreateNewCycle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NewCycleFormData&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;newCycle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Cycle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;getTime&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
      &lt;span class="na"&gt;task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;minutesAmount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;minutesAmount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;startDate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="nf"&gt;setCycles&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newCycle&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="nf"&gt;setActiveCycleId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newCycle&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="nf"&gt;setAmountSecondsPassed&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="c1"&gt;// Adicione essa linha&lt;/span&gt;

    &lt;span class="nf"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  4 - Timer no título do navegador &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Vamos agora alterar o title da página para mostrar o timer, ou seja, mostrar o timer na aba do navegador.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;activeCycle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;minutes&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;seconds&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;minutes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;seconds&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;activeCycle&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2F3q1mrbmw9g1n9lxsj5wf.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%2F3q1mrbmw9g1n9lxsj5wf.png" alt="código pra mostrar o timer na aba do navegador" width="800" height="710"&gt;&lt;/a&gt;&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%2F6jclt64uvcrhsnzv7kn9.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%2F6jclt64uvcrhsnzv7kn9.png" alt="resultado do timer na aba do navegador" width="800" height="571"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;OBS: Se não estiver na mesma aba, o timer no título não vai aparecer de 1 em 1 segundo certinho, pela questão que já foi comentada anteriormente sobre o &lt;code&gt;setInterval&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;commit: &lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/f33ba85ef22541797e39fcb962480c5254396154" rel="noopener noreferrer"&gt;feat: ✨ add &lt;code&gt;clearInterval&lt;/code&gt; and add timer to &lt;code&gt;document.title&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  5 - Interrompendo o ciclo &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

</description>
    </item>
    <item>
      <title>⚛️⏳Parte 3: Criando um Timer com Histórico em React</title>
      <dc:creator>Dev Maiqui 🇧🇷</dc:creator>
      <pubDate>Tue, 25 Feb 2025 23:26:30 +0000</pubDate>
      <link>https://forem.com/maiquitome/parte-3-criando-um-timer-com-historico-em-react-84n</link>
      <guid>https://forem.com/maiquitome/parte-3-criando-um-timer-com-historico-em-react-84n</guid>
      <description>&lt;p&gt;Seguindo com a terceira parte do projeto que construí na formação React da &lt;a href="https://app.rocketseat.com.br/cart/rocketseat-one?referral=maiquitome&amp;amp;coupon=indicamgm&amp;amp;utm_source=platform&amp;amp;utm_medium=organic&amp;amp;utm_campaign=venda&amp;amp;utm_term=mgm&amp;amp;utm_content=indication-lp_one" rel="noopener noreferrer"&gt;Rocketseat&lt;/a&gt;, um projeto de duas páginas/telas, onde uma tela contém o timer, e a outra tela contém o histórico dos ciclos realizados.&lt;/p&gt;

&lt;p&gt;Nesta terceira parte do projeto vamos focar no formulário, validação e desempenho.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Caso queira adquirir os cursos da Rocketseat com o meu cupom de desconto &lt;a href="https://app.rocketseat.com.br/cart/rocketseat-one?referral=maiquitome&amp;amp;coupon=indicamgm&amp;amp;utm_source=platform&amp;amp;utm_medium=organic&amp;amp;utm_campaign=venda&amp;amp;utm_term=mgm&amp;amp;utm_content=indication-lp_one" rel="noopener noreferrer"&gt;Acesse esse link&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links úteis:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer" rel="noopener noreferrer"&gt;Meu repositório do projeto&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/rocketseat-education/02-ignite-timer" rel="noopener noreferrer"&gt;Repositório oficial do Rocketseat&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.figma.com/community/file/1127351821076435124/ignite-timer" rel="noopener noreferrer"&gt;Figma do projeto feito pela Rocketseat&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Capítulos:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1 - Controlled vs Uncontrolled&lt;/li&gt;
&lt;li&gt;2 - O melhor dos dois mundos com &lt;code&gt;React Hook Form&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;3 - Usando &lt;code&gt;React Hook Form&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;4 - Validação com &lt;code&gt;Zod&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;5 - Validação com o botão habilitado&lt;/li&gt;
&lt;li&gt;6 - TypeScript no Formulário&lt;/li&gt;
&lt;li&gt;7 - Resetando o Formulário&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  1 - Controlled vs Uncontrolled &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Neste conteúdo vamos entender como podemos criar bons formulários em React. &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%2Fuqh644i2bji9ukumocdy.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%2Fuqh644i2bji9ukumocdy.png" alt="“form” da página home com botão desabilitado" width="730" height="528"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Olhando o nosso formulário da página &lt;code&gt;Home&lt;/code&gt; temos o campo onde colocamos o nome da tarefa e outro campo onde informamos por quanto tempo iremos trabalhar nessa tarefa. E, a primeira coisa que precisamos é de validação nesses campos, para que o usuário não faça o submit desse formulário sem preencher esses campos, ou preenchendo com o valor errado.&lt;/p&gt;

&lt;p&gt;Outra coisa é o botão que fica ativo somente quando todos os campos estiverem preenchidos. Então, precisamos monitorar de alguma forma se o usuário está preenchendo, se já preencheu esses campos, podemos dizer em tempo real, para só depois habilitar o botão.&lt;/p&gt;

&lt;p&gt;Há duas formas de trabalhar com formulários, a forma controlada e a forma não controlada (Controlled / Uncontrolled), e é muito importante entender esses dois termos, porque eles têm muito a ver como o React funciona. &lt;/p&gt;

&lt;p&gt;A forma controlada (Controlled) é sobre manter em tempo real o estado, a informação que o usuário insere na nossa aplicação numa variável do componente. Então há todo momento que o usuário estiver digitando no input, o estado é atualizado com a nova informação, assim sempre teremos o valor mais atual do que o usuário digitou.&lt;/p&gt;

&lt;p&gt;Estamos falando de formulário, mas isso pode ser usado em qualquer lugar que tenha um input.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Um exemplo fazendo da forma controlada:&lt;/strong&gt;&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%2Fd32rgx4agex90anl9jvp.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%2Fd32rgx4agex90anl9jvp.png" alt="usando o onchange no TaskInput" width="682" height="607"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como temos esse valor em tempo real, a gente consegue facilmente ter acesso a esse valor no momento de fazer o submit. E, facilmente, conseguimos refletir visualmente alterações na interface, baseado no valor desses inputs.&lt;/p&gt;

&lt;p&gt;Um exemplo disso é quando queremos habilitar o botão apenas quando o valor da tarefa esteja preenchido:&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%2F2lsbb88wo158owxrdffw.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%2F2lsbb88wo158owxrdffw.png" alt="Beneficio do input controlado" width="708" height="154"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Então &lt;code&gt;Controlled Components&lt;/code&gt; dentro do React, ou seja, qualquer componente que seja monitorado em tempo real o input do usuário, traz muita fluidez para mostrar ou deixar de mostrar algo na interface da aplicação, baseado nesse input do usuário.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O lado negativo do componente controlado&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Toda vez que a gente faz uma atualização de estado, a gente provoca uma nova renderização, ou seja, toda vez que o &lt;code&gt;setTask&lt;/code&gt; é chamado por qualquer motivo, o React precisa recalcular todo o conteúdo do componente, do estado que mudou. Isso de recalcular todo o conteúdo do componente, não necessariamente é lento, mas se a interface for muito complexa, com muita informação, pode, sim, virar um gargalo. &lt;/p&gt;

&lt;p&gt;Então em alguns casos, lidar com formulários desta maneira controlada, pode ser um problema para a aplicação em questão de desempenho. Na maioria das vezes não vai ser um problema, mas em alguns momentos, vai ser.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A forma &lt;code&gt;Uncontrolled&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Como seria então a forma &lt;code&gt;Uncontrolled&lt;/code&gt;?&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%2Fq95tld3s1amqdqyabu6y.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%2Fq95tld3s1amqdqyabu6y.png" alt="A forma  raw `Uncontrolled` endraw " width="688" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Desta forma &lt;code&gt;Uncontrolled&lt;/code&gt; a gente acaba perdendo a fluidez.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quando é indicado cada?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Controlled (Monitorado em tempo real)&lt;/code&gt;: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;formulários simples com poucos campos;&lt;/li&gt;
&lt;li&gt;interface simples;&lt;/li&gt;
&lt;li&gt;formulário de login, por exemplo;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;code&gt;Uncontrolled (Não Monitorado)&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;formulários gigantes com muitos campos;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  2 - O melhor dos dois mundos com &lt;code&gt;React Hook Form&lt;/code&gt; &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Nessa parte vamos utilizar a biblioteca &lt;a href="https://www.react-hook-form.com/" rel="noopener noreferrer"&gt;React Hook Form&lt;/a&gt;. Ela nos ajuda a trabalhar com &lt;code&gt;Controlled Components&lt;/code&gt; sem perder o desempenho, evitando renderizações desnecessárias.&lt;/p&gt;

&lt;p&gt;O &lt;code&gt;React Hook Form&lt;/code&gt; é uma biblioteca popular para gerenciar formulários em React por várias razões importantes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Performance otimizada&lt;/code&gt; - Minimiza a quantidade de re-renderizações usando um sistema de registro de campos não controlados, o que melhora significativamente a performance comparado com formulários controlados tradicionais.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Menos código&lt;/code&gt; - Reduz significativamente a quantidade de código necessário para gerenciar formulários. Você não precisa criar estados para cada campo nem gerenciar suas atualizações manualmente.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Validação eficiente&lt;/code&gt; - Oferece validação integrada e fácil de implementar, incluindo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Validação em tempo real&lt;/li&gt;
&lt;li&gt;Validação personalizada&lt;/li&gt;
&lt;li&gt;Integração com bibliotecas como Yup, Zod ou Joi&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Melhor experiência de desenvolvimento&lt;/code&gt; - Fornece:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tipagem forte com TypeScript&lt;/li&gt;
&lt;li&gt;DevTools para debugar&lt;/li&gt;
&lt;li&gt;Tratamento de erros intuitivo&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Gerenciamento de estados do formulário&lt;/code&gt; - Gerencia automaticamente estados como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;touched/untouched&lt;/li&gt;
&lt;li&gt;dirty/pristine&lt;/li&gt;
&lt;li&gt;validação&lt;/li&gt;
&lt;li&gt;submissão&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Para fazer a instalação execute o comando em seu terminal:&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="nv"&gt;$ &lt;/span&gt;npm i react-hook-form
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;commit: &lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/0af1307d71c628a246cb2ab0bc2f7cfe562dbafa" rel="noopener noreferrer"&gt;build: ➕ add react-hook-form lib &lt;code&gt;$ npm i react-hook-form&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  3 - Usando &lt;code&gt;React Hook Form&lt;/code&gt; &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;No arquivo &lt;code&gt;src/pages/Home/index.tsx&lt;/code&gt; vamos importar a função &lt;code&gt;useForm&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useForm&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-hook-form&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;useForm&lt;/code&gt; é um &lt;code&gt;hook&lt;/code&gt;. Por convenção, um &lt;code&gt;hook&lt;/code&gt; começa com &lt;code&gt;use&lt;/code&gt; no nome. Os &lt;code&gt;hooks&lt;/code&gt; são funções que acoplam uma funcionalidade em um componente existente.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;useForm()&lt;/code&gt; retorna um objeto, então conseguimos fazemos a desestruturação desse objeto, e as funções principais são &lt;code&gt;register&lt;/code&gt; e &lt;code&gt;handleSubmit&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&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="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;register&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleSubmit&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useForm&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;register&lt;/code&gt; é uma função que vai adicionar um input ao nosso formulário. &lt;code&gt;useForm()&lt;/code&gt; é como se a gente tivesse criado um novo formulário para a aplicação. E a função &lt;code&gt;register&lt;/code&gt; diz quais os campos que vamos ter no nosso formulário.&lt;/p&gt;

&lt;p&gt;Para registrar o &lt;code&gt;TaskInput&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TaskInput&lt;/span&gt;
 &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"task"&lt;/span&gt;
 &lt;span class="na"&gt;list&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"task-suggestions"&lt;/span&gt;
 &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Dê um nome para o seu projeto"&lt;/span&gt;
 &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;task&lt;/span&gt;&lt;span class="dl"&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;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A função &lt;code&gt;register&lt;/code&gt; recebe o &lt;code&gt;nome do input&lt;/code&gt; como argumento/valor e retorna vários métodos/funções e propriedades usadas no HTML:&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%2Fi631y1ltim83nmj7t618.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%2Fi631y1ltim83nmj7t618.png" alt="sugestões de autocomplete do vscode para o campo register" width="744" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Então com o &lt;u&gt;spread operator&lt;/u&gt; &lt;code&gt;{...register("task")}&lt;/code&gt; estamos pegando todos os métodos e as propriedades do &lt;code&gt;register&lt;/code&gt; e passando para o componente &lt;code&gt;TaskInput&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;E o mesmo para o &lt;code&gt;MinutesAmountInput&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MinutesAmountInput&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;"number"&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"minutesAmount"&lt;/span&gt;
  &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"00"&lt;/span&gt;
  &lt;span class="na"&gt;step&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;min&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;max&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;minutesAmount&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;valueAsNumber&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="si"&gt;}&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;code&gt;{ valueAsNumber: true }&lt;/code&gt; é para transformar de string para number.&lt;/p&gt;

&lt;h3&gt;
  
  
  Usando &lt;code&gt;handleSubmit&lt;/code&gt;
&lt;/h3&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%2F3yypjnphthulj994no12.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%2F3yypjnphthulj994no12.png" alt="usando handleSubmit" width="800" height="544"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Habilitando o botão (usando o watch)
&lt;/h3&gt;

&lt;p&gt;Com a função &lt;code&gt;watch&lt;/code&gt; podemos observar o campo e saber em tempo real o valor dele: &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%2F2xk2u3i8vjrvscepns0h.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%2F2xk2u3i8vjrvscepns0h.png" alt="usando watch" width="800" height="628"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Usando variáveis auxiliares
&lt;/h3&gt;

&lt;p&gt;Variáveis auxiliares são variáveis que não alteram a funcionalidade do código, mas melhoram a legibilidade do código.&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%2F8g02hee013jkxu4fvth4.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%2F8g02hee013jkxu4fvth4.png" alt="const isSubmitDisabled = !task" width="644" height="304"&gt;&lt;/a&gt;&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%2Fneedrxe4a4xiarbu5tal.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%2Fneedrxe4a4xiarbu5tal.png" alt="disabled={isSubmitDisabled}" width="786" height="178"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O commit desta parte infelizmente eu acabei deixando junto com a parte 5 e a parte 6 😕 recomendo fazer a separação 😅&lt;/p&gt;

&lt;p&gt;commit: &lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/22a325b8345a4f0f9c3ee3f19f7658ff2f1561db" rel="noopener noreferrer"&gt;feat: ✨ add controlled form with &lt;code&gt;react-hook-form&lt;/code&gt; and validation with &lt;code&gt;zod&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  4 - Validação com &lt;code&gt;Zod&lt;/code&gt; &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Por padrão, a biblioteca &lt;code&gt;React Hook Form&lt;/code&gt; não traz nenhuma funcionalidade de validação. Ela prefere ser uma biblioteca enxuta, com menos funcionalidades, assim o usuário consegue escolher bibliotecas complementares de sua preferência, como, por exemplo, bibliotecas de validação de formulários baseada em esquema, já que existem ótimas opções como: &lt;code&gt;Yup&lt;/code&gt;, &lt;code&gt;Zod&lt;/code&gt;, &lt;code&gt;Superstruct&lt;/code&gt; e &lt;code&gt;Joi&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Aqui vamos utilizar a &lt;a href="https://github.com/colinhacks/zod" rel="noopener noreferrer"&gt;Zod&lt;/a&gt;, pois traz mais integração com TypeScript:&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="nv"&gt;$ &lt;/span&gt;npm i zod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;commit: &lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/5c9f4120ca6d282982b8bd4c8e859b8917e34b48" rel="noopener noreferrer"&gt;build: ➕ add validation lib &lt;code&gt;$ npm i zod&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E para o &lt;code&gt;React Hook Form&lt;/code&gt; fazer a integração com essas bibliotecas de validação, precisamos instalar o pacote &lt;code&gt;@hookform/resolvers&lt;/code&gt;:&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="nv"&gt;$ &lt;/span&gt;npm i @hookform/resolvers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;commit: &lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/06153b7bd4f20978769655f169b6a4f3344c65ef" rel="noopener noreferrer"&gt;build: ➕ add lib to integrate react-hook-form with other libs &lt;code&gt;$ npm i @hookform/resolvers&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  5 - Validação com o botão habilitado &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Podemos ver na imagem abaixo que o botão fica desabilitado quando o campo está vazio:&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%2Fmtzn1h3q0rq45t85561f.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%2Fmtzn1h3q0rq45t85561f.png" alt="botão desabilitado quando o campo está vazio" width="699" height="519"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Neste caso, não precisaríamos de validação, mas como em muitos formulários não acontecem isso e necessitam informar ao usuário qual informação está incorreta, vamos habilitar o botão e realizar a validação do formulário.&lt;/p&gt;

&lt;p&gt;No arquivo &lt;code&gt;src/pages/Home/index.tsx&lt;/code&gt; vamos fazer a importação do Zod:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;zodResolver&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@hookform/resolvers/zod&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;zod&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;zod&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O código &lt;code&gt;* as zod&lt;/code&gt; é uma técnica do &lt;code&gt;ECMAScript Modules&lt;/code&gt; usado para importar tudo do pacote zod, já que ele não possui &lt;code&gt;export default&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Antes de utilizar o zod, podemos ver no &lt;code&gt;console.log(data)&lt;/code&gt; que adicionamos anteriormente neste mesmo arquivo, o formato do &lt;code&gt;data&lt;/code&gt; como sendo um objeto:&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%2Fgx99f2cn7urx3yx6qfoh.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%2Fgx99f2cn7urx3yx6qfoh.png" alt="código com o  raw `console.log(data)` endraw " width="604" height="130"&gt;&lt;/a&gt;&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%2Fwvmgzmyb8f0bu7zvbd7a.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%2Fwvmgzmyb8f0bu7zvbd7a.png" alt="formato de objeto aparecendo no console" width="800" height="537"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No mesmo arquivo vamos realizar a validação então de um objeto com &lt;code&gt;zod.object()&lt;/code&gt;:&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%2Ftsdrr87hf8o4wlzq6xjj.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%2Ftsdrr87hf8o4wlzq6xjj.png" alt="utilizando o  raw `zod.object()` endraw " width="738" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vamos verificar a validação dos minutos com o Zod, mas para fazer isso, precisamos comentar o código HTML que já faz essa validação:&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%2Fjrligdkel0t8ky104vrn.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%2Fjrligdkel0t8ky104vrn.png" alt="validação do HTML" width="800" height="438"&gt;&lt;/a&gt;&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%2Ft8xp888gtjxj8ku75mcq.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%2Ft8xp888gtjxj8ku75mcq.png" alt="comentando a validação do HTML" width="800" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora podemos testar a validação do Zod. Quando clicamos no botão, percebemos que nenhum resultado aparece no console do navegador, ou seja, não está chegando no &lt;code&gt;console.log&lt;/code&gt; pois estamos com erros de validação:&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%2Foork0cn48i1fjjdqnxjv.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%2Foork0cn48i1fjjdqnxjv.png" alt="Image description" width="800" height="575"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Visualizando os erros de validação do Zod
&lt;/h3&gt;

&lt;p&gt;Para visualizar os erros de validação do Zod, temos que usar o &lt;code&gt;formState&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Perceba que o &lt;code&gt;console.log(formState.errors)&lt;/code&gt; está fora da função &lt;code&gt;handleCreateNewCycle&lt;/code&gt;:&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%2Fdjee5801bb1tpq0bl108.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%2Fdjee5801bb1tpq0bl108.png" alt="Image description" width="800" height="355"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Assim já conseguimos visualizar a mensagem de erro:&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%2Fiekiqoukpvpe0epntp6g.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%2Fiekiqoukpvpe0epntp6g.png" alt="mensagem de erro do zod aparecendo no console do navegador" width="800" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Caso eu queira colocar uma mensagem diferente:&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%2Fi659c0rhtzrkvhxgqh8o.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%2Fi659c0rhtzrkvhxgqh8o.png" alt="mensagens de erro personalizadas" width="798" height="224"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Essas mensagens podem ser mostradas em tela para o usuário, mas nesse projeto, como temos a validação do campo númerico pelo HTML e o botão que só habilita quando há algo no campo de descrição, não iremos precisar mostrar essas mensagens ao usuário.&lt;/p&gt;

&lt;p&gt;Assim podemos remover o &lt;code&gt;formState&lt;/code&gt; e colocar o &lt;code&gt;max={60}&lt;/code&gt; devolta.&lt;/p&gt;

&lt;p&gt;O commit desta parte infelizmente eu acabei deixando junto com a parte 3 e parte 6 😕 recomendo fazer a separação 😅&lt;/p&gt;

&lt;p&gt;commit: &lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/22a325b8345a4f0f9c3ee3f19f7658ff2f1561db" rel="noopener noreferrer"&gt;feat: ✨ add controlled form with &lt;code&gt;react-hook-form&lt;/code&gt; and validation with &lt;code&gt;zod&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  6 - TypeScript no Formulário &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Agora vamos colocar uma tipagem para o &lt;code&gt;data: any&lt;/code&gt; como mostrado na imagem abaixo:&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%2F17h9krx8x7akzlfb4ikc.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%2F17h9krx8x7akzlfb4ikc.png" alt="data sem tipagem" width="758" height="258"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Podemos já deduzir qual será a tipagem olhando para o nosso formulário, um objeto; com esses dois campos:&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%2Fzvgbxfo15i4ifwaittyc.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%2Fzvgbxfo15i4ifwaittyc.png" alt="olhando o código do formulario" width="800" height="825"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Podemos criar a tipagem de forma manual com &lt;code&gt;interface&lt;/code&gt;:&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%2Fmzbcotcee82q4pzptzv0.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%2Fmzbcotcee82q4pzptzv0.png" alt="criando tipagem de forma manual com interface" width="752" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Existe uma propriedade chamada de &lt;code&gt;defaultValues&lt;/code&gt; que podemos passar pra o objeto de configuração dentro do &lt;code&gt;useForm&lt;/code&gt;, que nos permite setar valores iniciais para os campos:&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%2F788yzr2raj3xk37fishj.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%2F788yzr2raj3xk37fishj.png" alt=" raw `defaultValues` endraw  com valores iniciais nos campos" width="670" height="257"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se tentarmos usar o comando de autocomplete &lt;code&gt;Ctrl&lt;/code&gt; + &lt;code&gt;Space&lt;/code&gt;, não há sugestões válidas:&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%2Ffuhxa8fe3e2mwrbsm9fi.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%2Ffuhxa8fe3e2mwrbsm9fi.png" alt="sem autocomplete no  raw `defaultValues` endraw " width="800" height="411"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para obtermos o &lt;code&gt;autocomplete&lt;/code&gt; precisamos usar um &lt;code&gt;generic&lt;/code&gt;, como mostrado quando paramos o mouse em cima do &lt;code&gt;useForm&lt;/code&gt;, assim visualizamos os valores padrão &lt;code&gt;&amp;lt;{}, any&amp;gt;&lt;/code&gt;:&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%2Fi99dqmauaixo40h0vdxw.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%2Fi99dqmauaixo40h0vdxw.png" alt="mostrando generic do useForm" width="565" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Adicionando o &lt;code&gt;generic&lt;/code&gt; obtemos o autocomplete:&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%2F8v7jha2st0w4ujwpmsjd.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%2F8v7jha2st0w4ujwpmsjd.png" alt="adicionando o  raw `generic` endraw  no  raw `useForm` endraw " width="800" height="237"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Tipagem automática por inferência
&lt;/h3&gt;

&lt;p&gt;Olhando para o código abaixo jé podemos perceber os tipos pela estrutura:&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%2Fjj5n6u59f2s13wubbjv9.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%2Fjj5n6u59f2s13wubbjv9.png" alt="newCycleFormValidationSchema" width="800" height="251"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Usando &lt;code&gt;infer&lt;/code&gt; do TypeScript conseguimos extrair a tipagem do &lt;code&gt;zod.object()&lt;/code&gt; e, assim, podemos remover o &lt;code&gt;interface&lt;/code&gt;:&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%2Fr0asdzv4sxg5pqf5jigz.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%2Fr0asdzv4sxg5pqf5jigz.png" alt="inferencia de tipo usando infer" width="800" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note que usamos a palara &lt;code&gt;type&lt;/code&gt;, podemos assumir &lt;code&gt;interface&lt;/code&gt; quando criamos o tipo manualmente, e &lt;code&gt;type&lt;/code&gt; quando o tipo vem de forma automática.&lt;/p&gt;

&lt;h3&gt;
  
  
  Qual o benefício de usar o infer?
&lt;/h3&gt;

&lt;p&gt;Se no futuro precisássemos adicionar um campo novo, por exemplo, chamado de &lt;code&gt;owner&lt;/code&gt;, automaticamente o &lt;code&gt;infer&lt;/code&gt; adicionaria o tipo do campo. Parando o mouse em cima de &lt;code&gt;NewCycleFormData&lt;/code&gt; podemos notar o campo novo adicionado automaticamente:&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%2Ffbot0mvlqcmvnw31emct.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%2Ffbot0mvlqcmvnw31emct.png" alt="adicionando o campo owner como exemplo" width="800" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Isso é o diferencial do Zod e você pode conferir tudo isso na documentação oficial da bilioteca.&lt;/p&gt;

&lt;p&gt;O commit da parte 6 infelizmente eu acabei deixando junto com a parte 3 e parte 5 😕 recomendo fazer a separação 😅&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/22a325b8345a4f0f9c3ee3f19f7658ff2f1561db" rel="noopener noreferrer"&gt;feat: ✨ add controlled form with &lt;code&gt;react-hook-form&lt;/code&gt; and validation with &lt;code&gt;zod&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  7 - Resetando o Formulário &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Ao iniciar o timer clicando no botão &lt;code&gt;Começar&lt;/code&gt;, os campos não estão sendo resetados para o valor original. A biblioteca &lt;code&gt;React Hook Form&lt;/code&gt; fornece a função &lt;code&gt;reset&lt;/code&gt; para resetar os campos para os valores originais do &lt;code&gt;defaultValues&lt;/code&gt;:&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%2Fk1xygtxewgx5yj9hot5n.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%2Fk1xygtxewgx5yj9hot5n.png" alt="função  raw `reset` endraw  do  raw `React Hook Form` endraw " width="800" height="355"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>react</category>
      <category>typescript</category>
      <category>reactjsdevelopment</category>
    </item>
    <item>
      <title>⚛️⏳Parte 2: Criando um Timer com Histórico em React</title>
      <dc:creator>Dev Maiqui 🇧🇷</dc:creator>
      <pubDate>Sat, 01 Feb 2025 23:03:25 +0000</pubDate>
      <link>https://forem.com/maiquitome/parte-2-criando-um-timer-com-historico-em-react-3mk5</link>
      <guid>https://forem.com/maiquitome/parte-2-criando-um-timer-com-historico-em-react-3mk5</guid>
      <description>&lt;p&gt;Seguindo com a segunda parte do projeto que construí na formação React da &lt;a href="https://app.rocketseat.com.br/cart/rocketseat-one?referral=maiquitome&amp;amp;coupon=indicamgm&amp;amp;utm_source=platform&amp;amp;utm_medium=organic&amp;amp;utm_campaign=venda&amp;amp;utm_term=mgm&amp;amp;utm_content=indication-lp_one" rel="noopener noreferrer"&gt;Rocketseat&lt;/a&gt;, um projeto de duas páginas/telas, onde uma tela contém o timer, e a outra tela contém o histórico dos ciclos realizados.&lt;/p&gt;

&lt;p&gt;Nesta segunda parte do projeto vamos focar na criação das rotas, no layout e estilização das páginas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Caso queira adquirir os cursos da Rocketseat com o meu cupom de desconto &lt;a href="https://app.rocketseat.com.br/cart/rocketseat-one?referral=maiquitome&amp;amp;coupon=indicamgm&amp;amp;utm_source=platform&amp;amp;utm_medium=organic&amp;amp;utm_campaign=venda&amp;amp;utm_term=mgm&amp;amp;utm_content=indication-lp_one" rel="noopener noreferrer"&gt;Acesse esse link&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links úteis:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer" rel="noopener noreferrer"&gt;Meu repositório do projeto&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/rocketseat-education/02-ignite-timer" rel="noopener noreferrer"&gt;Repositório oficial do Rocketseat&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.figma.com/community/file/1127351821076435124/ignite-timer" rel="noopener noreferrer"&gt;Figma do projeto feito pela Rocketseat&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Capítulos:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
1 - Criando as rotas

&lt;ul&gt;
&lt;li&gt;1.1 - React Router DOM&lt;/li&gt;
&lt;li&gt;1.2 - Criando as páginas&lt;/li&gt;
&lt;li&gt;1.3 - Removendo o componente Button&lt;/li&gt;
&lt;li&gt;1.4 - Criando o arquivo de rotas&lt;/li&gt;
&lt;li&gt;1.5 - Context Providers&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

2 - Layout de rotas

&lt;ul&gt;
&lt;li&gt;2.1 - Criando o componente Header&lt;/li&gt;
&lt;li&gt;2.2 - Criando o &lt;code&gt;DefaultLayout&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

3 - Estilizando o Header

&lt;ul&gt;
&lt;li&gt;3.1 - Instalando o Phosphor Icons&lt;/li&gt;
&lt;li&gt;3.2 - Criando pasta para cada componente&lt;/li&gt;
&lt;li&gt;3.3 - Estilizando o DefaultLayout&lt;/li&gt;
&lt;li&gt;3.4 - Código do &lt;code&gt;Header/styles.ts&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;4 - Timer da Home Page&lt;/li&gt;

&lt;li&gt;5 - Finalizando a Home Page&lt;/li&gt;

&lt;li&gt;6 - Aprimorando inputs&lt;/li&gt;

&lt;li&gt;7 - Tabela da History Page&lt;/li&gt;

&lt;li&gt;8 - Status da Tabela da History Page 🟡🔴🟢&lt;/li&gt;

&lt;li&gt;9 - 🐛 &lt;code&gt;statusColour&lt;/code&gt; ➡️ &lt;code&gt;$statusColour&lt;/code&gt;
&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  1 - Criando as rotas &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Nesta primeira parte vamos focar na criação das rotas da aplicação. &lt;/p&gt;

&lt;p&gt;Uma rota é um padrão de URL que corresponde a uma determinada página ou recurso. &lt;/p&gt;

&lt;p&gt;Vamos supor que você tenha um blog com as seguintes URLs:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/&lt;/code&gt; (página inicial)&lt;br&gt;
&lt;code&gt;/sobre&lt;/code&gt; (página sobre)&lt;br&gt;
&lt;code&gt;/contato&lt;/code&gt; (página de contato)&lt;/p&gt;

&lt;p&gt;Você pode definir as seguintes rotas para essas URLs:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/&lt;/code&gt; -&amp;gt; &lt;code&gt;home()&lt;/code&gt; (função que renderiza a página inicial)&lt;br&gt;
&lt;code&gt;/sobre&lt;/code&gt; -&amp;gt; &lt;code&gt;about()&lt;/code&gt; (função que renderiza a página sobre)&lt;br&gt;
&lt;code&gt;/contato&lt;/code&gt; -&amp;gt; &lt;code&gt;contact()&lt;/code&gt; (função que renderiza a página de contato)&lt;/p&gt;

&lt;p&gt;Quando um usuário acessar &lt;code&gt;/sobre&lt;/code&gt;, o sistema de roteamento irá identificar a rota correspondente e executar a função &lt;code&gt;about()&lt;/code&gt;, que irá gerar o HTML da página "Sobre" e enviá-lo ao navegador do usuário.&lt;/p&gt;

&lt;p&gt;E, para criar as rotas, precisamos instalar a biblioteca que nos ajudará a fazer isso de uma forma mais fácil.&lt;/p&gt;
&lt;h3&gt;
  
  
  1.1 - React Router DOM &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Vamos instalar a biblioteca de roteamento com o comando:&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="nv"&gt;$ &lt;/span&gt;npm i react-router-dom
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;commit: &lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/19cea0105771a0ae9179bb82babd59e1cb850a07" rel="noopener noreferrer"&gt;chore: ➕ add route lib $ npm i react-router-dom&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1.2 - Criando as páginas &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Para testarmos as rotas, precisamos possuir as páginas, ou seja, os componentes que serão renderizados em tela quando uma URL for acessada.&lt;/p&gt;

&lt;p&gt;Vamos criar o arquivo &lt;code&gt;src/pages/History.tsx&lt;/code&gt; com o conteúdo:&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;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;History&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;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;History&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&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;E também o arquivo &lt;code&gt;src/pages/Home.tsx&lt;/code&gt; com o conteúdo:&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;export&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="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;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Home&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1.3 - Removendo o componente Button &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Vamos &lt;u&gt;apagar&lt;/u&gt; os arquivos &lt;code&gt;src/components/Button.tsx&lt;/code&gt; e &lt;code&gt;src/components/Button.styles.ts&lt;/code&gt;, já que eles eram apenas para mostrar como o &lt;code&gt;Styled Components&lt;/code&gt; funcionava.&lt;/p&gt;

&lt;p&gt;E no arquivo &lt;code&gt;src/App.tsx&lt;/code&gt; vamos remover o componente &lt;code&gt;Button&lt;/code&gt;:&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%2F2izkd3r4ox8i86qea6ev.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%2F2izkd3r4ox8i86qea6ev.png" alt="removendo o Button do arquivo  raw `src/App.tsx` endraw " width="517" height="561"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1.4 - Criando o arquivo de rotas &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Poderíamos colocar as rotas no arquivo &lt;code&gt;src/App.tsx&lt;/code&gt;, mas para uma melhor organização, vamos criar o arquivo &lt;code&gt;src/Router.tsx&lt;/code&gt; e colocar as rotas em um componente separado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Routes&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-router-dom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;History&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./pages/History&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Home&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./pages/Home&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Router&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Routes&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Route&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;element&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;lt;&lt;/span&gt;&lt;span class="nx"&gt;Home&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Route&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/history&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;element&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;lt;&lt;/span&gt;&lt;span class="nx"&gt;History&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Routes&lt;/span&gt;&lt;span class="err"&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;E no arquivo &lt;code&gt;src/App.tsx&lt;/code&gt; adicionamos o &lt;code&gt;&amp;lt;BrowserRouter&amp;gt;&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ThemeProvider&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BrowserRouter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-router-dom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Router&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./Router&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GlobalStyle&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./styles/global&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defaultTheme&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./styles/themes/default&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ThemeProvider&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;defaultTheme&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;BrowserRouter&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Router&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/BrowserRouter&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;GlobalStyle&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ThemeProvider&lt;/span&gt;&lt;span class="err"&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;Executando a nossa aplicação com &lt;code&gt;npm run dev&lt;/code&gt; no endereço &lt;code&gt;http://localhost:3000&lt;/code&gt; podemos ver a página &lt;code&gt;Home&lt;/code&gt;:&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%2Fz8h8a4s8tpehhkr4k4v8.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%2Fz8h8a4s8tpehhkr4k4v8.png" alt="página home" width="330" height="167"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E no endereço &lt;code&gt;http://localhost:3000/history&lt;/code&gt; podemos ver a página &lt;code&gt;History&lt;/code&gt;:&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%2Fdphh5wclu7bzfk5axg6h.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%2Fdphh5wclu7bzfk5axg6h.png" alt="página history" width="306" height="145"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;commit: &lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/7738ebfc897918fd5d8d2778556c6bf74262ceb5" rel="noopener noreferrer"&gt;feat: ✨ add Router&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1.5 - Context Providers &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Você pôde perceber no arquivo &lt;code&gt;src/App.tsx&lt;/code&gt;, que tanto o &lt;code&gt;&amp;lt;ThemeProvider&amp;gt;&lt;/code&gt; quanto o , que não produzem nada visualmente na tela, são componentes que precisam ficar por fora dos nossos componentes que produzem algo visual na tela. E, tanto o &lt;code&gt;&amp;lt;ThemeProvider&amp;gt;&lt;/code&gt; como o , são chamados de &lt;code&gt;Context Providers&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Os &lt;code&gt;Context Providers&lt;/code&gt; não produzem nenhum visual em tela, mas produzem um contexto para os componentes que estão dentro deles, ou seja, passam informações para esses componentes que estão dentro, no intuito desses componentes interiores saberem do contexto de fora.&lt;/p&gt;




&lt;h2&gt;
  
  
  2 - Layout de rotas &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Nesta parte vamos entender o que é &lt;code&gt;Layout de Rotas&lt;/code&gt; e como isso pode ajudar no desempenho da aplicação.&lt;/p&gt;

&lt;p&gt;Olhando para as páginas, podemos observar que o &lt;code&gt;Header&lt;/code&gt; se repete, independente da rota que acessarmos:&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%2Frk61e3trdffijtb03xao.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%2Frk61e3trdffijtb03xao.png" alt="mostrando o header se repetindo nas duas páginas" width="800" height="259"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se em cada componente de página, nós adicionarmos o código do &lt;code&gt;Header&lt;/code&gt; dentro, cada acesso do usuário em cada página, o &lt;code&gt;Header&lt;/code&gt; estará sendo recriado, construído em tela do absoluto zero.&lt;/p&gt;

&lt;p&gt;Podemos então deixar o código do &lt;code&gt;Header&lt;/code&gt; em um único lugar para ser criado do zero apenas uma vez, melhorando assim o desempenho da aplicação.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.1 - Criando o componente Header &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Vamos criar o arquivo &lt;code&gt;src/components/Header.tsx&lt;/code&gt; com o conteúdo:&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;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Header&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;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Header&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&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;E poderíamos ter em cada página o &lt;code&gt;Header&lt;/code&gt;:&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%2F0iykxiw2sdyxfkvnpisd.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%2F0iykxiw2sdyxfkvnpisd.png" alt="header na página Home" width="639" height="380"&gt;&lt;/a&gt;&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%2F8byh2kgsp3rkfu27uupd.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%2F8byh2kgsp3rkfu27uupd.png" alt="header na página History" width="640" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Podemos ver que funciona:&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%2Fb7aqfcae588n3a7yow7r.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%2Fb7aqfcae588n3a7yow7r.png" alt="rota Home funcionando com header, não performático" width="342" height="206"&gt;&lt;/a&gt;&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%2F8vkf6pyxsfy6aihiyyn9.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%2F8vkf6pyxsfy6aihiyyn9.png" alt="rota History funcionando com header, não performático" width="307" height="175"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mas se o &lt;code&gt;Header&lt;/code&gt; vai estar em todas as páginas, tem jeito melhor de fazer, mais performático!&lt;/p&gt;

&lt;h3&gt;
  
  
  2.2 - Criando o &lt;code&gt;DefaultLayout&lt;/code&gt; &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Vamos criar o Layout Padrão que também será um componente, criando por primeiro o arquivo &lt;code&gt;src/layouts/DefaultLayout.tsx&lt;/code&gt; com o conteúdo:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Outlet&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-router-dom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Header&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../components/Header&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;DefaultLayout&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="p"&gt;&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;Outlet&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="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;O &lt;code&gt;&amp;lt;Outlet /&amp;gt;&lt;/code&gt; é um espaço para inserir um conteúdo, um conteúdo que irá mudar dependendo da rota. Se a rota for &lt;code&gt;/&lt;/code&gt; então o conteúdo de &lt;code&gt;Outlet&lt;/code&gt; será do componente &lt;code&gt;Home&lt;/code&gt;, se a rota for &lt;code&gt;/history&lt;/code&gt; então o conteúdo de &lt;code&gt;Outlet&lt;/code&gt; será do componente &lt;code&gt;History&lt;/code&gt;. Ainda não irá funcionar, pois precisamos alterar as nossas rotas.&lt;/p&gt;

&lt;p&gt;No arquivo &lt;code&gt;src/Router.tsx&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Routes&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-router-dom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;DefaultLayout&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./layouts/DefaultLayout&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;History&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./pages/History&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Home&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./pages/Home&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Router&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;Routes&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;Route&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt; &lt;span class="na"&gt;element&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="nc"&gt;DefaultLayout&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;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Route&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt; &lt;span class="na"&gt;element&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="nc"&gt;Home&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;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Route&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/history"&lt;/span&gt; &lt;span class="na"&gt;element&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="nc"&gt;History&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;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* 
      - Um Exemplo de um layout diferente:

      - Para acessar a rota: "/admin/products"

      &amp;lt;Route path="/admin" element={&amp;lt;AdminLayout /&amp;gt;}&amp;gt;
        &amp;lt;Route path="/" element={&amp;lt;Home /&amp;gt;} /&amp;gt;
        &amp;lt;Route path="/products" element={&amp;lt;History /&amp;gt;} /&amp;gt;
      &amp;lt;/Route&amp;gt; 

      - Nesse caso todas as rotas que começarem com `path="/admin"` terão `&amp;lt;AdminLayout /&amp;gt;` aplicado.
      */&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;Routes&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;O &lt;code&gt;&amp;lt;Route path="/" element={&amp;lt;DefaultLayout /&amp;gt;}&amp;gt;&lt;/code&gt; envolve as rotas &lt;code&gt;Home&lt;/code&gt; e &lt;code&gt;History&lt;/code&gt;, e o &lt;code&gt;path="/"&lt;/code&gt; foi colocado, pois queremos aplicar o &lt;code&gt;DefaultLayout&lt;/code&gt; para todas as rotas.&lt;/p&gt;

&lt;p&gt;Se ao invés de &lt;code&gt;path="/"&lt;/code&gt; fosse &lt;code&gt;path="/teste"&lt;/code&gt;, o &lt;code&gt;DefaultLayout&lt;/code&gt; seria aplicado para todas as rotas que começassem com &lt;code&gt;/teste&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;commit: &lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/d39b1ebf17399a0664e2973808bf3cc183b08e82" rel="noopener noreferrer"&gt;feat: ✨ add DefaultLayout&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  3 - Estilizando o Header &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Nesta parte vamos estilizar o &lt;code&gt;Header&lt;/code&gt; e a caixa por volta como na imagem abaixo:&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%2Fkfsirfxdyfgqcq76kgyh.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%2Fkfsirfxdyfgqcq76kgyh.png" alt="Header estilizado" width="800" height="553"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3.1 - Instalando o Phosphor Icons &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Vamos utilizar uma família de ícones chamada &lt;a href="https://phosphoricons.com/" rel="noopener noreferrer"&gt;Phosphor Icons&lt;/a&gt; e instalar a bilioteca &lt;a href="https://github.com/phosphor-icons/react/tree/legacy" rel="noopener noreferrer"&gt;phosphor-react&lt;/a&gt;&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="nv"&gt;$ &lt;/span&gt;npm i phosphor-react
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Atualmente já existe uma biblioteca mais nova renomeada de &lt;a href="https://github.com/phosphor-icons/react" rel="noopener noreferrer"&gt;@phosphor-icons/react&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;commit: &lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/119361336be0c15bc38e04560f04c88991f1ab32" rel="noopener noreferrer"&gt;build: ➕ add icon lib &lt;code&gt;$ npm i phosphor-react&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3.2 - Criando pasta para cada componente &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Vamos adotar apartir de agora uma organização para cada componente, já que vamos ter um arquivo de estilização no formato &lt;code&gt;ts&lt;/code&gt; do &lt;code&gt;Styled Components&lt;/code&gt; para cada componente.&lt;/p&gt;

&lt;p&gt;Vamos fazer a refatoração do arquivo &lt;code&gt;src/layouts/DefaultLayout.tsx&lt;/code&gt;, renomeando ele para &lt;code&gt;src/layouts/DefaultLayout/index.tsx&lt;/code&gt;. Na mesma pasta vamos criar o arquivo de estilização &lt;code&gt;src/layouts/DefaultLayout/styles.ts&lt;/code&gt;:&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%2F71kg8msaapgtueb1f17b.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%2F71kg8msaapgtueb1f17b.png" alt="pasta DefaultLayout" width="210" height="71"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Na mesma pasta do componente também podemos ter futuramente &lt;code&gt;arquivos de teste&lt;/code&gt; e &lt;code&gt;arquivos de tipagem&lt;/code&gt;, tudo relacionado ao componente por exemplo.&lt;/p&gt;

&lt;p&gt;Vamos fazer outra refatoração parecida, agora com o &lt;code&gt;Header&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;src/components/Header.tsx&lt;/code&gt; -&amp;gt; &lt;code&gt;src/components/Header/index.tsx&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;E vamos criar o arquivo &lt;code&gt;src/components/Header/styles.ts&lt;/code&gt;&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%2Fadpz6nbnep5pj1vnd7q0.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%2Fadpz6nbnep5pj1vnd7q0.png" alt="pasta do Header" width="206" height="72"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3.3 - Estilizando o DefaultLayout &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Vamos criar um componente estilizado chamado &lt;code&gt;LayoutContainer&lt;/code&gt; no arquivo &lt;code&gt;src/layouts/DefaultLayout/styles.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&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;styled-components&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;LayoutContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="s2"&gt;`
  max-width: 74rem;
  height: calc(100vh - 10rem);
  margin: 5rem auto;
  padding: 2.5rem;
  background: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gray-800&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;;
  border-radius: 8px;
  display: flex;
  flex-direction: column;
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E no arquivo &lt;code&gt;src/layouts/DefaultLayout/index.tsx&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Outlet&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-router-dom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Header&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../../components/Header&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;LayoutContainer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./styles&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;DefaultLayout&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;LayoutContainer&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;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;Outlet&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;LayoutContainer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explicação do CSS:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;1 - &lt;code&gt;styled.div&lt;/code&gt;: A tag &lt;code&gt;div&lt;/code&gt; foi escolhida pois se encaixa melhor nesse cenário, já que estamos criando a caixa onde ficará todo o conteúdo da página. A tag &lt;code&gt;main&lt;/code&gt; NÃO foi escolhida nesse caso pois haverá o &lt;code&gt;header&lt;/code&gt; e o &lt;code&gt;footer&lt;/code&gt; dentro dessa tag, e a &lt;code&gt;main&lt;/code&gt; seria mais apropriada para conter a funcionalidade principal da página.&lt;/p&gt;

&lt;p&gt;2 - &lt;code&gt;max-width: 74rem;&lt;/code&gt;: &lt;code&gt;70rem (1120px)&lt;/code&gt; é a largura da caixa, e somando mais o padding &lt;code&gt;2rem (32px)&lt;/code&gt; para cada lado, temos os &lt;code&gt;74rem&lt;/code&gt; de largura. &lt;/p&gt;

&lt;p&gt;Podemos ver o tamanho da caixa no Figma conforme a imagem abaixo:&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%2Fsik0w0yiw22jyeb0j1eg.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%2Fsik0w0yiw22jyeb0j1eg.png" alt="imagem do Figma mostrando o tamanho da caixa de 1120px" width="800" height="548"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E conforme a gente dominui o tamanho no navegador, os &lt;code&gt;2rem&lt;/code&gt; de padding se mantém:&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%2F582wfa99ml27o7u9bm42.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%2F582wfa99ml27o7u9bm42.png" alt="imagem do Projeto mostrando o tamanho do padding" width="800" height="833"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para essa margem de &lt;code&gt;2rem&lt;/code&gt; funcionar tive que adiconar &lt;code&gt;margin: 2rem&lt;/code&gt; no arquivo &lt;code&gt;src/styles/global.ts&lt;/code&gt;:&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%2Fupjdfjfwx5gfu2oak82t.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%2Fupjdfjfwx5gfu2oak82t.png" alt="mostra o  raw `margin-inline: 2rem;` endraw  sendo adicionado no arquivo  raw `global.ts` endraw " width="800" height="337"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;margin-inline: 2rem;&lt;/code&gt; é a mesma coisa que &lt;code&gt;margin: 0 2rem;&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;OBS: Essa alteração não estatá junto do commit desta parte do artigo, pois apenas verifiquei isso no momento que eu estava escrevendo essa parte do artigo, já que não foi explicado nas aulas da Rocketseat.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;3 - &lt;code&gt;height: calc(100vh - 10rem);&lt;/code&gt;: &lt;code&gt;100vh&lt;/code&gt; é para que a caixa ocupe a altura inteira da página menos os &lt;code&gt;10rem&lt;/code&gt; da margem (&lt;code&gt;5rem&lt;/code&gt; de margem no topo e &lt;code&gt;5rem&lt;/code&gt; de margem no bottom).&lt;/p&gt;

&lt;p&gt;4 - &lt;code&gt;margin: 5rem auto;&lt;/code&gt;: A margem possui &lt;code&gt;5rem (80px)&lt;/code&gt; de top e &lt;code&gt;5rem (80px)&lt;/code&gt; de bottom, como mostrado na imagem do Figma abaixo:&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%2Fwsxq6abghw0izdl30gmz.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%2Fwsxq6abghw0izdl30gmz.png" alt="imagem do Figma mostrando o tamanho da margem da caixa de 80px de top e 80px de bottom" width="800" height="334"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;OBS: Para essas linhas laranjas com os valores das margens aparecerem no Figma, é preciso clicar na caixa e depois segurar a tecla &lt;code&gt;option&lt;/code&gt; no Mac ou &lt;code&gt;alt&lt;/code&gt; no Windows/Linux, e mover o mouse para a área desejada.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Já o valor &lt;code&gt;auto&lt;/code&gt; para as laterais faz com que automaticamente seja calculado um valor de forma igual para cada margem lateral, assim o conteúdo acaba ficando centralizado.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.4 - Código do &lt;code&gt;Header/styles.ts&lt;/code&gt; &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Vamos adicionar o CSS no arquivo &lt;code&gt;src/components/Header/styles.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&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;styled-components&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;HeaderContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="s2"&gt;`
  display: flex;
  align-items: center;
  justify-content: space-between;
  nav {
    display: flex;
    gap: 0.5rem;
    a {
      width: 3rem;
      height: 3rem;
      display: flex;
      justify-content: center;
      align-items: center;
      color: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gray-100&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;;
      border-top: 3px solid transparent;
      border-bottom: 3px solid transparent;
      &amp;amp;:hover {
        border-bottom: 3px solid &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;green-500&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;;
      }
      &amp;amp;.active {
        color: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;green-500&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;;
      }
    }
  }
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Caso você não esteja familizarizado com essa sintaxe &lt;code&gt;&amp;amp;.active&lt;/code&gt; e &lt;code&gt;&amp;amp;:hover&lt;/code&gt; recomendo olhar sobre &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_nesting/Using_CSS_nesting" rel="noopener noreferrer"&gt;CSS nesting&lt;/a&gt;. Essa sintaxe começou a aparecer no &lt;a href="https://sass-lang.com/" rel="noopener noreferrer"&gt;SASS&lt;/a&gt; e depois introduzido no CSS, por isso, favor verificar a compatibilidade dos navegadores no &lt;a href="https://caniuse.com/?search=css%20nesting" rel="noopener noreferrer"&gt;Can I use&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No arquivo &lt;code&gt;src/components/Header/index.tsx&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;HeaderContainer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./styles&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Scroll&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Timer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;phosphor-react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;logoIgnite&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;../../assets/logo-ignite.svg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NavLink&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-router-dom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Header&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;HeaderContainer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &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="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;logoIgnite&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="s"&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;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;nav&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;NavLink&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Timer"&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;Timer&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;24&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;NavLink&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;NavLink&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/history"&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Histórico"&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;Scroll&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;24&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;NavLink&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;nav&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;HeaderContainer&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;O SVG do &lt;strong&gt;logo&lt;/strong&gt; você pode pegar no &lt;a href="https://www.figma.com/community/file/1127351821076435124/ignite-timer" rel="noopener noreferrer"&gt;Figma do projeto feito pela Rocketseat&lt;/a&gt; ou também está disponível no commit: &lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/97be88757a926add8a91a16359627b51f0811996" rel="noopener noreferrer"&gt;feat: 💄 style Header and DefaultLayout&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  4 - Timer da Home Page &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Nesta parte vamos começar a estilizar a página Home e, ao final, teremos esse resultado:&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%2Fj96jyj0d6hrgch2pal5l.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%2Fj96jyj0d6hrgch2pal5l.png" alt="estilizando o timer da home" width="761" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Após criar a pasta &lt;code&gt;Home&lt;/code&gt; em &lt;code&gt;src/pages/Home&lt;/code&gt;, coloque o arquivo &lt;code&gt;src/pages/Home.tsx&lt;/code&gt; dentro desta pasta &lt;code&gt;Home&lt;/code&gt; e renomeie o arquivo de &lt;code&gt;Home.tsx&lt;/code&gt; para &lt;code&gt;index.tsx&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;src/pages/Home.tsx&lt;/code&gt; ➡️ &lt;code&gt;src/pages/Home/index.tsx&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Nesse novo arquivo &lt;code&gt;src/pages/Home/index.tsx&lt;/code&gt; adicione o código abaixo:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Play&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;phosphor-react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;CountdownContainer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;FormContainer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;HomeContainer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Separator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./styles&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&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;HomeContainer&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;form&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;FormContainer&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;label&lt;/span&gt; &lt;span class="na"&gt;htmlFor&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"task"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Vou trabalhar em&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&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;input&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"task"&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;label&lt;/span&gt; &lt;span class="na"&gt;htmlFor&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"minutesAmount"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;durante&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&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;input&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;"number"&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"minutesAmount"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;minutos.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;FormContainer&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;CountdownContainer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;0&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;0&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Separator&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;Separator&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;0&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;0&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;CountdownContainer&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;"submit"&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;Play&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
          Começar
        &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;form&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;HomeContainer&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;Nas aulas da Rocketseat não foi usada a &lt;a href="https://developer.mozilla.org/en-US/docs/Learn_web_development/Core/Styling_basics/Values_and_units" rel="noopener noreferrer"&gt;unidade relativa &lt;code&gt;rem&lt;/code&gt;&lt;/a&gt; para os ícones, mas eu acho bem interessante manter tudo com &lt;code&gt;rem&lt;/code&gt;. Caso você queira usar o tamanho relativo do ícone em &lt;code&gt;rem&lt;/code&gt; você pode usar desta forma abaixo &lt;a href="https://github.com/phosphor-icons/react/tree/legacy?tab=readme-ov-file#props" rel="noopener noreferrer"&gt;como explicado na documentação&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* 24/16 = 1.5 */&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;Play&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"1.5rem"&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;Vamos criar o arquivo de estilos &lt;code&gt;src/pages/Home/styles.ts&lt;/code&gt; com o código:&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;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;HomeContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="s2"&gt;`
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  form {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3.5rem;
  }
`&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;FormContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="s2"&gt;`
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  color: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gray-100&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;;
  font-size: 1.125rem;
  font-weight: bold;
  flex-wrap: wrap;
`&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;CountdownContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="s2"&gt;`
  font-family: "Roboto Mono", monospace;
  font-size: 10rem;
  line-height: 8rem;
  color: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gray-100&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;;
  display: flex;
  gap: 1rem;
  span {
    background: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gray-700&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;;
    padding: 2rem 1rem;
    border-radius: 8px;
  }
`&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;Separator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="s2"&gt;`
  padding: 2rem 0;
  color: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;green-500&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;;
  width: 4rem;
  overflow: hidden;
  display: flex;
  justify-content: center;
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essa parte do &lt;code&gt;Timer da Home Page&lt;/code&gt; a princípio não há nenhuma novidade, nada que a gente não tenha visto antes mas, caso você esteja com dúvida ainda com esse código, incentivo você a voltar para a &lt;code&gt;Parte 1&lt;/code&gt; onde é explicado detalhadamente sobre &lt;code&gt;Styled Components&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Segue o commit desta parte: &lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/b645507e899e80027ba090572bf79da3eb69fd33" rel="noopener noreferrer"&gt;feat: 💄 style home countdown&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  5 - Finalizando a Home Page &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Ao finalizar essa parte teremos a &lt;code&gt;Home&lt;/code&gt; assim:&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%2Faa1hxgwnwvqudmub3hog.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%2Faa1hxgwnwvqudmub3hog.png" alt="Home Page finalizada" width="700" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vamos criar mais componentes estilizados. Uma dica quando estamos utilizando &lt;code&gt;Styled Components&lt;/code&gt; é evitar usar código em cascata e focar em criar componentes estilizados.&lt;/p&gt;

&lt;p&gt;Por exemplo, poderíamos fazer o seguinte código para estilizarmos o botão, conforme mostra a imagem abaixo:&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%2F7rmra5u1qyxxmuvey4qo.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%2F7rmra5u1qyxxmuvey4qo.png" alt="código css do botão dentro do componente HomeContainer" width="800" height="617"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mas isso não é indicado, dê preferência para criar um componente estilizado para esse botão, e é isso que vamos fazer nomeando esse componente de &lt;code&gt;&amp;lt;StartCountdownButton&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;E o código final do aqruivo &lt;code&gt;src/pages/Home/index.tsx&lt;/code&gt; será esse:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Play&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;phosphor-react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;CountdownContainer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;FormContainer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;HomeContainer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;MinutesAmountInput&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Separator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;StartCountdownButton&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;TaskInput&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./styles&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&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;HomeContainer&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;form&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;FormContainer&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;label&lt;/span&gt; &lt;span class="na"&gt;htmlFor&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"task"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Vou trabalhar em&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&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;TaskInput&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"task"&lt;/span&gt; &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Dê um nome para o seu projeto"&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;label&lt;/span&gt; &lt;span class="na"&gt;htmlFor&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"minutesAmount"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;durante&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&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;MinutesAmountInput&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;"number"&lt;/span&gt;
            &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"minutesAmount"&lt;/span&gt;
            &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"00"&lt;/span&gt;
          &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;minutos.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;FormContainer&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;CountdownContainer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;0&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;0&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Separator&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;Separator&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;0&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;0&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;CountdownContainer&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;StartCountdownButton&lt;/span&gt; &lt;span class="na"&gt;disabled&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;"submit"&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;Play&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
          Começar
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;StartCountdownButton&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;form&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;HomeContainer&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;E o código final do arquivo de estilização &lt;code&gt;src/pages/Home/styles.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&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;styled-components&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;HomeContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="s2"&gt;`
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  form {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3.5rem;
  }
`&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;FormContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="s2"&gt;`
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  color: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gray-100&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;;
  font-size: 1.125rem;
  font-weight: bold;
  flex-wrap: wrap;
`&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;BaseInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="s2"&gt;`
  background: transparent;
  height: 2.5rem;
  border: 0;
  border-bottom: 2px solid &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gray-500&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;;
  font-weight: bold;
  font-size: 1.125rem;
  padding: 0 0.5rem;
  color: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gray-100&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;;
  &amp;amp;:focus {
    box-shadow: none;
    border-color: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;green-500&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;;
  }
  &amp;amp;::placeholder {
    color: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gray-500&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;;
  }
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TaskInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;BaseInput&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;`
  flex: 1;
`&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;MinutesAmountInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;BaseInput&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;`
  width: 4rem;
`&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;CountdownContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="s2"&gt;`
  font-family: "Roboto Mono", monospace;
  font-size: 10rem;
  line-height: 8rem;
  color: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gray-100&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;;
  display: flex;
  gap: 1rem;
  span {
    background: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gray-700&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;;
    padding: 2rem 1rem;
    border-radius: 8px;
  }
`&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;Separator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="s2"&gt;`
  padding: 2rem 0;
  color: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;green-500&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;;
  width: 4rem;
  overflow: hidden;
  display: flex;
  justify-content: center;
`&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;StartCountdownButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="s2"&gt;`
  width: 100%;
  border: 0;
  padding: 1rem;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  font-weight: bold;
  cursor: pointer;
  background: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;green-500&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;;
  color: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gray-100&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;;
  &amp;amp;:disabled {
    opacity: 0.7;
    cursor: not-allowed;
  }
  &amp;amp;:not(:disabled):hover {
    background: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;green-700&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;;
  }
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nesse código temos algo novo que é o &lt;code&gt;styled(BaseInput)&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BaseInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="s2"&gt;`
  background: transparent;
  height: 2.5rem;
  border: 0;
  border-bottom: 2px solid &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gray-500&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;;
  font-weight: bold;
  font-size: 1.125rem;
  padding: 0 0.5rem;
  color: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gray-100&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;;
  &amp;amp;:focus {
    box-shadow: none;
    border-color: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;green-500&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;;
  }
  &amp;amp;::placeholder {
    color: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gray-500&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;;
  }
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TaskInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;BaseInput&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;`
  flex: 1;
`&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;MinutesAmountInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;BaseInput&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;`
  width: 4rem;
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usando o &lt;code&gt;styled(BaseInput)&lt;/code&gt; estamos criando um componente tendo como base o componente &lt;code&gt;BaseInput&lt;/code&gt;, ou seja, estamos fazendo herança de estilização, assim evitamos repetir código.&lt;/p&gt;

&lt;p&gt;commit dessa parte: &lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/05ac5494d66cc3df54fc6e2af224923911bd9494" rel="noopener noreferrer"&gt;feat: 💄 finish styling the home&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  6 - Aprimorando inputs &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Vamos adicionar &lt;code&gt;step={5}&lt;/code&gt; para quando clicado na seta ir aumentando de 5 em 5 minutos, um &lt;code&gt;min={5}&lt;/code&gt; para aceitar no mínimo 5 minutos, e &lt;code&gt;max={60}&lt;/code&gt; para aceitar no máximo 60 minutos, ou seja, uma hora.&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%2Fldil68gi3ncojvitgkmu.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%2Fldil68gi3ncojvitgkmu.png" alt="input number" width="240" height="73"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E também vamos adicionar o &lt;code&gt;&amp;lt;datalist&amp;gt;&lt;/code&gt; que trará sugestões de projetos já feitos:&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%2F203gbdwd962syb0ilmqa.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%2F203gbdwd962syb0ilmqa.png" alt="input com datalist" width="697" height="509"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Altere o arquivo &lt;code&gt;src/pages/Home/index.tsx&lt;/code&gt;:&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%2Fp8wzh5dzivpbyxw5m7cl.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%2Fp8wzh5dzivpbyxw5m7cl.png" alt="git do arquivo  raw `src/pages/Home/index.tsx` endraw " width="516" height="651"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Caso queira sumir com a seta do &lt;code&gt;&amp;lt;datalist&amp;gt;&lt;/code&gt; no arquivo &lt;code&gt;src/pages/Home/styles.ts&lt;/code&gt;:&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%2Fy5zg2fgr0r4oszar6lej.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%2Fy5zg2fgr0r4oszar6lej.png" alt="git do  raw `src/pages/Home/styles.ts` endraw " width="477" height="279"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Esse código para sumir com a seta é específico para o browser &lt;code&gt;Google Chrome&lt;/code&gt;. Para cada browser há uma maneira específica de sumir com a seta.&lt;/p&gt;

&lt;p&gt;commit: &lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/24035daee1e8be8e24c7d08c2bfece001a13bcee" rel="noopener noreferrer"&gt;feat: ✨ add datalist&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  7 - Tabela da History Page &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Nesta parte iremos construir e estilizar a tabela, no final o resultado será esse:&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%2Foth2sr2dx69juzdmx16j.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%2Foth2sr2dx69juzdmx16j.png" alt="tabela da página history" width="800" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Após criar a pasta &lt;code&gt;History&lt;/code&gt; em &lt;code&gt;src/pages/History&lt;/code&gt;, coloque o arquivo &lt;code&gt;src/pages/History.tsx&lt;/code&gt; dentro desta pasta &lt;code&gt;History&lt;/code&gt; e renomeie o arquivo de &lt;code&gt;History.tsx&lt;/code&gt; para &lt;code&gt;index.tsx&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;src/pages/History.tsx&lt;/code&gt; ➡️ &lt;code&gt;src/pages/History/index.tsx&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Nesse novo arquivo &lt;code&gt;src/pages/History/index.tsx&lt;/code&gt; adicione o código abaixo:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;HistoryContainer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;HistoryList&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./styles&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;History&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;HistoryContainer&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;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Meu histórico&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&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;HistoryList&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;thead&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;th&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Tarefa&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;th&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;th&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Duração&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;th&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;th&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Duração&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;th&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;th&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Status&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;th&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;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;thead&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;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;tr&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;Tarefa&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;20 minutos&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;Há 2 meses&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;Concluído&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;&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;td&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Tarefa&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;20 minutos&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;Há 2 meses&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;Concluído&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;&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;td&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Tarefa&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;20 minutos&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;Há 2 meses&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;Concluído&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;&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;td&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Tarefa&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;20 minutos&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;Há 2 meses&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;Concluído&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;&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;td&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Tarefa&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;20 minutos&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;Há 2 meses&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;Concluído&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;&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;td&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Tarefa&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;20 minutos&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;Há 2 meses&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;Concluído&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;&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;td&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Tarefa&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;20 minutos&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;Há 2 meses&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;Concluído&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;&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="nc"&gt;HistoryList&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;HistoryContainer&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;Nesta mesma pasta crie o arquivo de estilização &lt;code&gt;src/pages/History/styles.ts&lt;/code&gt; com o código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&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;styled-components&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;HistoryContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="s2"&gt;`
  flex: 1;
  padding: 3.5rem;
  display: flex;
  flex-direction: column;
  h1 {
    font-size: 1.5rem;
    color: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gray-100&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;;
  }
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;HistoryList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="s2"&gt;`
  flex: 1;
  overflow: auto;
  margin-top: 2rem;
  table {
    width: 100%;
    border-collapse: collapse;
    min-width: 600px;
    th {
      background-color: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gray-600&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;;
      padding: 1rem;
      text-align: left;
      color: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gray-100&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;;
      font-size: 0.875rem;
      line-height: 1.6;
      &amp;amp;:first-child {
        border-top-left-radius: 8px;
        padding-left: 1.5rem;
      }
      &amp;amp;:last-child {
        border-top-right-radius: 8px;
        padding-right: 1.5rem;
      }
    }
    td {
      background-color: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gray-700&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;;
      border-top: 4px solid &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gray-800&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;;
      padding: 1rem;
      font-size: 0.875rem;
      line-height: 1.6;
      &amp;amp;:first-child {
        width: 50%;
        padding-left: 1.5rem;
      }
      &amp;amp;:last-child {
        padding-right: 1.5rem;
      }
    }
  }
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Porque esse &lt;code&gt;&amp;lt;HistoryList&amp;gt;&lt;/code&gt; foi criado? No mobile há uma dificuldade em mostrar tabelas, e esse &lt;code&gt;&amp;lt;HistoryList&amp;gt;&lt;/code&gt; foi criado para que quando a tela estiver no tamanho de mobile, o usuário consiga dar scroll para o lado. Não há como fazer scroll com &lt;code&gt;table&lt;/code&gt; apenas com &lt;code&gt;div&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;O que faz esse &lt;code&gt;border-collapse: collapse;&lt;/code&gt;? junta duas bordas da tabela em uma só borda. Se cada borda possui &lt;code&gt;1px&lt;/code&gt; quando as colunas se encontrarem ao invés da borda ter &lt;code&gt;2px&lt;/code&gt;, terá apenas uma borda de &lt;code&gt;1px&lt;/code&gt;. Resumindo mantém todas as linhas da tabela na mesma proporção.&lt;/p&gt;

&lt;p&gt;commit: &lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/24ff477f137ec079472c3478426a7b8f763a1afc" rel="noopener noreferrer"&gt;feat: ✨ add History page with styles&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  8 - Status da Tabela da History Page 🟡🔴🟢 &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Agora vamos para o código das cores do indicador da coluna de status:&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%2Fpjyl8z0kgr9q9vgvr9tp.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%2Fpjyl8z0kgr9q9vgvr9tp.png" alt="coluna de status com as bolinhas coloridas" width="199" height="491"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pederíamos criar um componente React para &lt;code&gt;&amp;lt;Status&amp;gt;&lt;/code&gt; mas nesse caso como será utilizado apenas na página &lt;code&gt;History&lt;/code&gt;, vamos criar somente um &lt;code&gt;Styled Component&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Nesse caso, não vou colocar o código aqui pois é mais interessante visualizar as alterações no GitHub, então por favor acesse o commit abaixo:&lt;/p&gt;

&lt;p&gt;commit: &lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/8cf37493e3d704419bd2cae990a7def840b8d437" rel="noopener noreferrer"&gt;feat: ✨ add status color to History page&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  9 - 🐛 &lt;code&gt;statusColour&lt;/code&gt; ➡️ &lt;code&gt;$statusColour&lt;/code&gt; &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Agora vamos corrigir um bug, acessando o seu terminal do navegador provavelmente você verá um erro parecido com esse:&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%2Fd4puox4vla7wh30vm4xv.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%2Fd4puox4vla7wh30vm4xv.png" alt="bug do status color" width="800" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alguns alunos da Rocketseat comentaram sobre esse bug no &lt;a href="https://github.com/rocketseat-education/02-ignite-timer/commit/1ea6d7b#diff-21f4dd2a68b5327188fcd8e98419eb81ef218b9af0e9cedb45cf4b5b267f80a3R74" rel="noopener noreferrer"&gt;commit da aula&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para corrigir o problema eu segui a documentação do &lt;a href="https://styled-components.com/docs/basics#passed-props" rel="noopener noreferrer"&gt;Styled Components&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E a minha solução está nesse commit: &lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/f74e3c9a6c68425be8cf8072acc6b1ac285244ad" rel="noopener noreferrer"&gt;🐛 change statusColour to $statusColour&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E assim finalizamos a parte 2 🎉&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>react</category>
      <category>reactjsdevelopment</category>
      <category>typescript</category>
    </item>
    <item>
      <title>⚛️⏳Parte 1: Criando um Timer com Histórico em React</title>
      <dc:creator>Dev Maiqui 🇧🇷</dc:creator>
      <pubDate>Thu, 30 Jan 2025 13:32:39 +0000</pubDate>
      <link>https://forem.com/maiquitome/parte-1-criando-um-timer-com-historico-em-react-2800</link>
      <guid>https://forem.com/maiquitome/parte-1-criando-um-timer-com-historico-em-react-2800</guid>
      <description>&lt;p&gt;Neste artigo vou mostrar um dos projetos que construí na formação React da &lt;a href="https://app.rocketseat.com.br/cart/rocketseat-one?referral=maiquitome&amp;amp;coupon=indicamgm&amp;amp;utm_source=platform&amp;amp;utm_medium=organic&amp;amp;utm_campaign=venda&amp;amp;utm_term=mgm&amp;amp;utm_content=indication-lp_one" rel="noopener noreferrer"&gt;Rocketseat&lt;/a&gt;, um projeto de duas páginas/telas, onde uma tela contém o timer, e a outra tela contém o histórico dos ciclos realizados.&lt;/p&gt;

&lt;p&gt;Já que uma das melhores maneiras de se aprender é ensinando, resolvi criar esta postagem para revisitar e fixar melhor os fundamentos da biblioteca React.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Caso queira adquirir os cursos da Rocketseat com o meu cupom de desconto &lt;a href="https://app.rocketseat.com.br/cart/rocketseat-one?referral=maiquitome&amp;amp;coupon=indicamgm&amp;amp;utm_source=platform&amp;amp;utm_medium=organic&amp;amp;utm_campaign=venda&amp;amp;utm_term=mgm&amp;amp;utm_content=indication-lp_one" rel="noopener noreferrer"&gt;Acesse esse link&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ao longo do projeto vamos ver sobre vários assuntos:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Estilização com &lt;code&gt;Styled Components&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;Roteamento de páginas com &lt;code&gt;React Router&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;Distribuição de estado com &lt;code&gt;Context API&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;Efeito colateral do hook &lt;code&gt;useEffect&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;entre outros assuntos...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nesta primeira parte iremos cobrir a estrutura da aplicação, a criação do projeto e a utilização da biblioteca &lt;code&gt;Styled Components&lt;/code&gt; para estilização da nossa aplicação.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links úteis:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer" rel="noopener noreferrer"&gt;Meu repositório do projeto&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/rocketseat-education/02-ignite-timer" rel="noopener noreferrer"&gt;Repositório oficial do Rocketseat&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.figma.com/community/file/1127351821076435124/ignite-timer" rel="noopener noreferrer"&gt;Figma do projeto feito pela Rocketseat&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Capítulos:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
1 - Criação do projeto

&lt;ul&gt;
&lt;li&gt;1.1 - Usando o Vite &lt;/li&gt;
&lt;li&gt;1.2 - Instalando as dependências&lt;/li&gt;
&lt;li&gt;1.3 - (Opcional) Removendo arquivos desnecessários&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

2 - Styled Components

&lt;ul&gt;
&lt;li&gt;2.1 - Instalando o pacote&lt;/li&gt;
&lt;li&gt;2.2 - Instalação da tipagem&lt;/li&gt;
&lt;li&gt;2.3 - Instale a extensão no VSCode&lt;/li&gt;
&lt;li&gt;2.4 - Entendendo como funciona o &lt;code&gt;styled-components&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;2.5 - Configurando Temas&lt;/li&gt;
&lt;li&gt;2.6 - Tipagem de Temas&lt;/li&gt;
&lt;li&gt;2.7 - Estilos Globais&lt;/li&gt;
&lt;li&gt;2.8 - Cores e fonte&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  1 - Criação do projeto &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1.1 - Usando o Vite &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Vamos criar o projeto usando uma ferramenta chamada &lt;a href="https://vite.dev/guide/" rel="noopener noreferrer"&gt;Vite&lt;/a&gt; que consegue fazer toda a configuração de um projeto frontend, configurando, por exemplo, o bundler e o compiler da nossa aplicação, nos poupando bastante tempo.&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="nv"&gt;$ &lt;/span&gt;npm create vite@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Após executar o comando, dê um nome para a aplicação, após selecione React e TypeScript.&lt;/p&gt;

&lt;p&gt;commit: &lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/6739ecbde0847284caff066f4f7443fb7950ec8e" rel="noopener noreferrer"&gt;feat: 🎉 add initial structure &lt;code&gt;$ npm create vite@latest&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1.2 - Instalando as dependências &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Após o projeto ter sido criado, na raiz do projeto, instale as dependências com o comando:&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="nv"&gt;$ &lt;/span&gt;npm i
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;commit: &lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/875a4c378b9fa598749cdbce9a6f1dee60d39a08" rel="noopener noreferrer"&gt;build: 🔧 install dependencies &lt;code&gt;$ npm i&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1.3 - (Opcional) Removendo arquivos desnecessários &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;commit: &lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/1803be489f4d06be5a3c20ea7e78b89bba6163a9" rel="noopener noreferrer"&gt;refactor: 🔥 remove vite unused files&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2 - Styled Components &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1 - Instalando o pacote &lt;a href="https://styled-components.com/docs/basics#installation" rel="noopener noreferrer"&gt;styled-components&lt;/a&gt; &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Execute o comando na raiz do projeto:&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="nv"&gt;$ &lt;/span&gt;npm i styled-components
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;commit: &lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/121b54fdfe8ee7a2397089ed57721f8c153d47db" rel="noopener noreferrer"&gt;build: ➕ add styled-components &lt;code&gt;$ npm i styled-components&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2.2 - Instalação da tipagem &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;O pacote &lt;code&gt;styled-components&lt;/code&gt; era um daqueles pacotes que não traziam a tipagem do TypeScript junto dele:&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%2Ffobcyrxad9dt85kvnhwk.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%2Ffobcyrxad9dt85kvnhwk.png" alt="styled-components versão 5 sem tipagem" width="800" height="429"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;desta forma, era preciso instalar a tipagem separadamente com esse comando:&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="c"&gt;# NÃO É MAIS PRECISO INSTALAR&lt;/span&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;npm i @types/styled-components &lt;span class="nt"&gt;-D&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;-D&lt;/code&gt; é uma abreviatura de &lt;code&gt;--save-dev&lt;/code&gt; que significa que será instalado apenas para desenvolvimento, ou seja, essa biblioteca não fará parte do &lt;code&gt;build&lt;/code&gt; final da aplicação em produção. Isso porque o código TypeScript é convertido todo para JavaScript, então os tipos não serão usados no código final em produção.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hoje em dia nas &lt;u&gt;versões mais atuais&lt;/u&gt;, &lt;strong&gt;isso não é mais preciso&lt;/strong&gt;, pois a tipagem já vem junto dele:&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%2F5hxtfqzfrhd8vewi8a7y.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%2F5hxtfqzfrhd8vewi8a7y.png" alt="styled-components versão 6 com tipagem" width="800" height="412"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Você pode ignorar os commits abaixo&lt;/strong&gt;, pois um deles possue a instalação dos tipos e o outro a desinstalação. Isso ocorreu, pois as aulas do Rocketseat estavam desatualizadas no momento. Mas como eu instalei a versão mais recente, pude desinstalar sem problema o pacote dos tipos.&lt;/p&gt;

&lt;p&gt;commit: &lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/1b2c8b17a982b4d6e7e501037f140052a7e95214" rel="noopener noreferrer"&gt;build: ➕ add types of styled-components &lt;code&gt;$ npm i @types/styled-components -D&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;commit: &lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/a5a974054b723ec64a6788d0f04482b0f9cc474f" rel="noopener noreferrer"&gt;build: ➖ remove &lt;code&gt;@types/styled-components&lt;/code&gt; with &lt;code&gt;$ npm uninstall @types/styled-components&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2.3 - Instale a extensão no VSCode &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=styled-components.vscode-styled-components" rel="noopener noreferrer"&gt;vscode-styled-components&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Essa extensão habilita o &lt;code&gt;Syntax highlighting&lt;/code&gt;, ou seja, deixa o código CSS colorido dentro do &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates" rel="noopener noreferrer"&gt;Tagged templates&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2.4 - Entendendo como funciona o &lt;code&gt;styled-components&lt;/code&gt; &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Vamos criar um componente de botão para exemplificar o funcionamento do &lt;code&gt;styled-components&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Crie o arquivo &lt;code&gt;src/components/Button.tsx&lt;/code&gt;com o código:&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;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Button&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="p"&gt;&amp;gt;&lt;/span&gt;Enviar&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em &lt;code&gt;src/App.tsx&lt;/code&gt; vamos repetir várias vezes o botão em tela:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./components/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;export&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="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;Button&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
   &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
   &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
   &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&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;blockquote&gt;
&lt;p&gt;Os sinais &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt; e &lt;code&gt;&amp;lt;/&amp;gt;&lt;/code&gt; chamado &lt;code&gt;Fragment&lt;/code&gt; é usado quando precisamos colocar vários components dentro sem precisar de uma tag &lt;code&gt;div&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&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%2Ffbf0mro0cjr0r4t2v63x.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%2Ffbf0mro0cjr0r4t2v63x.png" alt="aparecendo 4 botões em tela sem estilização" width="586" height="138"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vamos agora adicionar uma propriedade para mudar a cor do botão.&lt;/p&gt;

&lt;p&gt;Em &lt;code&gt;src/components/Button.tsx&lt;/code&gt; adicionamos uma tipagem das cores aceitas para cada botão:&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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ButtonProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;primary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;secondary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;danger&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;success&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;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ButtonProps&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="p"&gt;&amp;gt;&lt;/span&gt;Enviar&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em &lt;code&gt;src/App.tsx&lt;/code&gt;, para cada botão, vamos adicionar a propriedade de cor &lt;code&gt;variant&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./components/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;export&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="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;Button&lt;/span&gt; &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"primary"&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;Button&lt;/span&gt; &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"secondary"&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;Button&lt;/span&gt; &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"success"&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;Button&lt;/span&gt; &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"danger"&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;Button&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;Quando estamos utilizando o CSS tradicional, para estilizar precisamos utilizar as classes. Para isso, vamos utilizar o &lt;a href="https://dev.to/gmantovani97/porque-utilizar-css-modules-no-react-1a93"&gt;css-modules&lt;/a&gt; apenas para este exemplo, pois, mais adiante, vamos utilizar apenas o &lt;code&gt;styled-components&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Criando o arquivo de &lt;code&gt;css-modules&lt;/code&gt; em &lt;code&gt;src/components/Button.module.css&lt;/code&gt; com as classes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;40px&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;vamos importar os estilos e colocar o &lt;code&gt;className&lt;/code&gt; em &lt;code&gt;src/components/Button.tsx&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styles&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;./Button.module.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ButtonProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;primary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;secondary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;danger&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;success&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;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ButtonProps&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="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;button&lt;/span&gt;&lt;span class="si"&gt;}&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="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;e o resultado agora são botões com tamanhos maiores:&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%2F550iq4ip6ti4eweeevrm.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%2F550iq4ip6ti4eweeevrm.png" alt="botões com estilização e tamanhos maiores" width="800" height="125"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;e com as cores no mesmo arquivo &lt;code&gt;src/components/Button.tsx&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styles&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;./Button.module.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ButtonProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;primary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;secondary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;danger&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;success&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;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;variant&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;primary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;ButtonProps&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="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="s2"&gt;`&lt;/span&gt;&lt;span class="p"&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;button&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;color&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;Enviar&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora falta criar as classes para as cores. No arquivo de CSS &lt;code&gt;src/components/Button.module.css&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;40px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.primary&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;purple&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.secondary&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;orange&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.danger&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.success&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;green&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;e o resultado das cores é esse:&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%2F9t70qhih77vqpkiymwls.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%2F9t70qhih77vqpkiymwls.png" alt="botões com cores" width="795" height="153"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Refatorando usando &lt;code&gt;Styled Components&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Vamos renomear o arquivo de CSS &lt;code&gt;src/components/Button.module.css&lt;/code&gt; para ➡️ &lt;code&gt;src/components/Button.styles.ts&lt;/code&gt; terminando exatamente com &lt;code&gt;.ts&lt;/code&gt; e o conteúdo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&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;styled-components&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ButtonContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="s2"&gt;`
  width: 100px;
  height: 40px;
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;e voltando no arquivo &lt;code&gt;src/components/Button.tsx&lt;/code&gt; vamos trocar a tag &lt;code&gt;button&lt;/code&gt; para &lt;code&gt;ButtonContainer&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ButtonContainer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./Button.styles&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ButtonProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;primary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;secondary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;danger&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;success&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;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;variant&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;primary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;ButtonProps&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="nc"&gt;ButtonContainer&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;ButtonContainer&lt;/span&gt;&lt;span class="p"&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;Como resultado temos os botões com os mesmos tamanhos, pois definimos o &lt;code&gt;height&lt;/code&gt; e o &lt;code&gt;width&lt;/code&gt; no &lt;code&gt;ButtonContainer&lt;/code&gt;:&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%2Fk1xus4m7eo2huwt4raoo.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%2Fk1xus4m7eo2huwt4raoo.png" alt="botões com os mesmos tamanhos usando styled components" width="800" height="155"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Podemos definir a cor adicionando &lt;code&gt;variant={variant}&lt;/code&gt; no mesmo arquivo &lt;code&gt;src/components/Button.tsx&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ButtonContainer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./Button.styles&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ButtonProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;primary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;secondary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;danger&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;success&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;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;variant&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;primary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;ButtonProps&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="nc"&gt;ButtonContainer&lt;/span&gt; &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;variant&lt;/span&gt;&lt;span class="si"&gt;}&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;ButtonContainer&lt;/span&gt;&lt;span class="p"&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;e no arquivo de estilização &lt;code&gt;src/components/Button.styles.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&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;styled-components&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ButtonContainerProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;primary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;secondary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;danger&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;success&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;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ButtonContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="s2"&gt;`
  width: 100px;
  height: 40px;
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;nesse mesmo arquivo vamos criar um tipo para variant:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&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;styled-components&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ButtonVariant&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;primary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;secondary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;danger&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;success&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ButtonContainerProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ButtonVariant&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;ButtonContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="s2"&gt;`
  width: 100px;
  height: 40px;
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E no arquivo &lt;code&gt;src/components/Button.tsx&lt;/code&gt; vamos importar e usar essa tipagem:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ButtonContainer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ButtonVariant&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./Button.styles&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ButtonProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;ButtonVariant&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;function&lt;/span&gt; &lt;span class="nf"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;variant&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;primary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;ButtonProps&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="nc"&gt;ButtonContainer&lt;/span&gt; &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;variant&lt;/span&gt;&lt;span class="si"&gt;}&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;ButtonContainer&lt;/span&gt;&lt;span class="p"&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;Para completar a tipagem e fazer uso dela, vamos adicionar &lt;code&gt;&amp;lt;ButtonContainerProps&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&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;styled-components&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ButtonVariant&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;primary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;secondary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;danger&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;success&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ButtonContainerProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ButtonVariant&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;ButtonContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ButtonContainerProps&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;`
  width: 100px;
  height: 40px;
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tipagem feita, agora precisamos setar as cores no mesmo arquivo de estilização &lt;code&gt;src/components/Button.styles.ts&lt;/code&gt; adicionando a constante &lt;code&gt;buttonVariants&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&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;styled-components&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ButtonVariant&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;primary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;secondary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;danger&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;success&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ButtonContainerProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ButtonVariant&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;buttonVariants&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;purple&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;secondary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;orange&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;danger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;green&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;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ButtonContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ButtonContainerProps&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;`
  width: 100px;
  height: 40px;
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;e fazendo uma interpolação de strings &lt;code&gt;${}&lt;/code&gt;, o &lt;code&gt;Styled Components&lt;/code&gt; envia todas as propriedades automaticamente para a função:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&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;styled-components&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ButtonVariant&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;primary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;secondary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;danger&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;success&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ButtonContainerProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ButtonVariant&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;buttonVariants&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;purple&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;secondary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;orange&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;danger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;green&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;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ButtonContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ButtonContainerProps&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;`
  width: 100px;
  height: 40px;

  &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;props&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="s2"&gt;`background-color: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;buttonVariants&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
  &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="s2"&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;code&gt;props.variant&lt;/code&gt; é o valor que vem automaticamente do arquivo do componente do botão.&lt;/p&gt;

&lt;p&gt;E o resultado com as cores permanece identicando:&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%2Fpekfnv2ctwtqglzpdszc.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%2Fpekfnv2ctwtqglzpdszc.png" alt="botões com cores usando styled components" width="800" height="153"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Conclusão do Styled Components: A vantagem é não precisar usar multiplas classes para a estilização e mantendo um scopo de componente.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Apenas uma melhoria na questão de &lt;code&gt;Syntax highlighting&lt;/code&gt;:&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%2Fwk5jxdr410e3thmcm2ra.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%2Fwk5jxdr410e3thmcm2ra.png" alt="sem css syntax highlighting" width="800" height="229"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para melhorar podemos importar o css e acrescentar a palavra css na frente da &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals" rel="noopener noreferrer"&gt;template literals&lt;/a&gt;:&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%2F35hgko40smm71300bbwm.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%2F35hgko40smm71300bbwm.png" alt="com css syntax highlighting" width="800" height="633"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;commit: &lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/920fac95dc843a3ab2d5f066d2ab4eb0090da3cd" rel="noopener noreferrer"&gt;feat: ✨ add button component to understand about &lt;code&gt;styled-components&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2.5 - Configurando Temas &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Crie o arquivo &lt;code&gt;src/styles/themes/default.ts&lt;/code&gt; com o seguinte código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;defaultTheme&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;white&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#FFF&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#8257e6&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;secondary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;orange&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;No arquivo &lt;code&gt;src/App.tsx&lt;/code&gt; vamos importar o &lt;code&gt;defaultTheme&lt;/code&gt; e vamos passar como valor a propriedade &lt;code&gt;theme&lt;/code&gt; do &lt;code&gt;ThemeProvider&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ThemeProvider&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./components/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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defaultTheme&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./styles/themes/default&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&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;ThemeProvider&lt;/span&gt; &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;defaultTheme&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;Button&lt;/span&gt; &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"primary"&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;Button&lt;/span&gt; &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"secondary"&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;Button&lt;/span&gt; &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"success"&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;Button&lt;/span&gt; &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"danger"&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;Button&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;ThemeProvider&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;blockquote&gt;
&lt;p&gt;Se tivessemos mais de um tema, poderíamos trocar o valor &lt;code&gt;defaultTheme&lt;/code&gt; para &lt;code&gt;lightTheme&lt;/code&gt; por exemplo: &lt;code&gt;theme={lightTheme}&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Podemos acessar as cores do tema usando &lt;code&gt;props.theme.nomeDaPropriedade&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="s2"&gt;`
  background-color: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;primary&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;;
`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No arquivo do botão &lt;code&gt;src/components/Button.styles.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="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;ButtonContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ButtonContainerProps&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;`
  width: 100px;
  height: 40px;
  border-radius: 4px;
  border: 0;
  margin: 8px;
  background-color: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;primary&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;;
  color: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;white&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;;
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;e temos esse resultado:&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%2F7oopvh8mxz7e180e9in5.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%2F7oopvh8mxz7e180e9in5.png" alt="botões com o tema aplicado" width="800" height="143"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;commit: &lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/54e48e3803c0e0fc2f65cc16aaae2afadb7f8369" rel="noopener noreferrer"&gt;feat: ✨ add themes&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2.6 - Tipagem de Temas &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Temos um problema de autocomplete ao digitar &lt;code&gt;props.theme.&lt;/code&gt; o VSCode não nos fornece as opções disponíveis, isso acontece por falta de configuração de tipagem:&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%2Fryss8n9ow3ydv4o7ng0c.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%2Fryss8n9ow3ydv4o7ng0c.png" alt="sem autocomplete ao digitar  raw `props.theme.` endraw " width="800" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para corrigir isso, vamos criar um arquivo no diretório &lt;code&gt;src/@types/styled.d.ts&lt;/code&gt;. &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%2Fswe0scqxs8mfsuje5d5i.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%2Fswe0scqxs8mfsuje5d5i.png" alt="pasta @types" width="242" height="186"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A nomenclatura &lt;code&gt;@types&lt;/code&gt; foi usada nesse caso simplismente para permanecer no topo da árvore de pastas. Além de ficar com o ícone do TypeScript.&lt;/p&gt;

&lt;p&gt;Já a nomenclatura do arquivo &lt;code&gt;styled.d.ts&lt;/code&gt; terminando com &lt;code&gt;d.ts&lt;/code&gt;, indica que esse arquivo possuí &lt;strong&gt;apenas&lt;/strong&gt; &lt;u&gt;código de tipagem do TypeScript&lt;/u&gt;, chamado de arquivo de definição de tipos.&lt;/p&gt;

&lt;p&gt;Nesse arquivo &lt;code&gt;src/@types/styled.d.ts&lt;/code&gt; vamos adicionar duas importações:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defaultTheme&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../styles/themes/default&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;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%2Fnf2pvzhof54jwikq29ue.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%2Fnf2pvzhof54jwikq29ue.png" alt="ponteiro do mouse descansando em cima da const  raw `defaultTheme` endraw " width="800" height="323"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A imagem acima mostra o ponteiro do mouse descansando em cima da const &lt;code&gt;defaultTheme&lt;/code&gt;, indicando que a devolução do valor é do tipo objeto, com as propriedades do tipo string, ou seja, mostra a tipagem do &lt;code&gt;defaultTheme&lt;/code&gt;. Isso acontece pois o TypeScript cria a tipagem de forma automática pra gente, mas existe uma forma de nós acessarmos isso e guardar em uma variável com o seguinte código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ThemeType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;defaultTheme&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// ThemeType poderia ter qualquer nome&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fegpcvclp8qtu4s5wgnvv.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%2Fegpcvclp8qtu4s5wgnvv.png" alt="guardando o tipo em uma variável" width="738" height="329"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Na imagem acima podemos perceber que o tipo gerado (inferência de tipo) para o &lt;code&gt;defaultTheme&lt;/code&gt; foi guardado dentro de &lt;code&gt;ThemeType&lt;/code&gt;, isso graças ao &lt;code&gt;typeof&lt;/code&gt; que capturou a tipagem do &lt;code&gt;defaultTheme&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;No arquivo &lt;code&gt;src/@types/styled.d.ts&lt;/code&gt; vamos fazer o uso do &lt;code&gt;declare module&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defaultTheme&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../styles/themes/default&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;ThemeType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;defaultTheme&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;declare&lt;/span&gt; &lt;span class="kr"&gt;module&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Aqui vamos subscrever a tipagem do DefaultTheme&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;code&gt;declare module&lt;/code&gt; cria uma tipagem para o módulo &lt;code&gt;styled-components&lt;/code&gt; do NPM, e toda vez que o &lt;code&gt;styled-components&lt;/code&gt; for importado, a tipagem, a definição de tipos que vai ser puxada, vai ser o que foi definido dentro do scopo do &lt;code&gt;declare module&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Como queremos apenas subscrever algo de dentro do &lt;code&gt;declare module&lt;/code&gt;, e não criar toda uma tipagem nova, nós tivemos que fazer a importação &lt;code&gt;import "styled-components";&lt;/code&gt; e fazer a declaração com o &lt;code&gt;declare module "styled-components"&lt;/code&gt;. Sem a importação estaríamos criando tudo do zero a definição de tipos do pacote &lt;code&gt;styled-components&lt;/code&gt;.&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%2F3f6kuqlrt3vcjzewukkg.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%2F3f6kuqlrt3vcjzewukkg.png" alt="theme sem tipagem" width="800" height="716"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Na imagem acima, mostra o arquivo &lt;code&gt;src/components/Button.styles.ts&lt;/code&gt;, e nele o ponteiro do mouse está parado em cima da palavra &lt;code&gt;theme&lt;/code&gt;. Se clicar em cima de &lt;code&gt;theme&lt;/code&gt; segurando a tecla &lt;code&gt;ctrl&lt;/code&gt; ou &lt;code&gt;command&lt;/code&gt;, é direcionado para o arquivo de tipos do &lt;code&gt;styled-components&lt;/code&gt;:&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%2Feo4thutb0l4q2cutk5zy.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%2Feo4thutb0l4q2cutk5zy.png" alt="arquivo de tipos do  raw `styled-components` endraw " width="800" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora clicando em cima de &lt;code&gt;DefaultTheme&lt;/code&gt; em laranja, é direcionado para a exportação da tipagem do &lt;code&gt;DefaultTheme&lt;/code&gt;:&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%2Fex2et4j4a7zgdjimq0q0.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%2Fex2et4j4a7zgdjimq0q0.png" alt="exportação da tipagem do  raw `DefaultTheme` endraw " width="800" height="195"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Na imagem acima, podemos ver que o objeto &lt;code&gt;{}&lt;/code&gt; do &lt;code&gt;DefaultTheme&lt;/code&gt; exportado está vazio, pois esse objeto foi feito para ser subscrito pelas nossas tipagens. &lt;/p&gt;

&lt;p&gt;Então o código final do arquivo &lt;code&gt;src/@types/styled.d.ts&lt;/code&gt; ficará assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defaultTheme&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../styles/themes/default&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;ThemeType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;defaultTheme&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// subescreve a tipagem do DefaultTheme&lt;/span&gt;
&lt;span class="kr"&gt;declare&lt;/span&gt; &lt;span class="kr"&gt;module&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;DefaultTheme&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;ThemeType&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 no arquivo &lt;code&gt;src/components/Button.styles.ts&lt;/code&gt; podemos ver a tipagem funcionando:&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%2Fmt98yhxkrw8kp8sxi7i0.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%2Fmt98yhxkrw8kp8sxi7i0.png" alt="tipagem funcionando para o tema" width="800" height="622"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;e se tentar colocar uma propriedade que não existe, um erro será acusado:&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%2Fj57ehpu18bmh1f6t5okg.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%2Fj57ehpu18bmh1f6t5okg.png" alt="erro ao usar propriedade que não existe" width="800" height="271"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;commit: &lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/bec41b24c474850e2b93cc6d27bb9f2da4638fa2" rel="noopener noreferrer"&gt;feat: ✨ add type to themes and override &lt;code&gt;DefaultTheme&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2.7 - Estilos Globais &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Criando o arquivo no diretório &lt;code&gt;src/styles/global.ts&lt;/code&gt;. Mais uma vez terminando com &lt;code&gt;.ts&lt;/code&gt; pois estamos utilizando &lt;code&gt;styled-components&lt;/code&gt;. Todo CSS global vamos colocar nesse arquivo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createGlobalStyle&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GlobalStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createGlobalStyle&lt;/span&gt;&lt;span class="s2"&gt;`
  * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
  }
  body {
    background: #333;
    color: #FFF;
  }
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vamos agora importar no arquivo &lt;code&gt;src/App.tsx&lt;/code&gt; e utilizar:&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%2F9fgzcueqi7rax0b5lv18.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%2F9fgzcueqi7rax0b5lv18.png" alt="utilizando estilos globais do styled-components" width="506" height="452"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ThemeProvider&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./components/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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GlobalStyle&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./styles/global&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defaultTheme&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./styles/themes/default&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&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;ThemeProvider&lt;/span&gt; &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;defaultTheme&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;Button&lt;/span&gt; &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"primary"&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;Button&lt;/span&gt; &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"secondary"&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;Button&lt;/span&gt; &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"success"&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;Button&lt;/span&gt; &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"danger"&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;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="cm"&gt;/* tanto faz a posição do &amp;lt;GlobalStyle /&amp;gt; dentro do ThemeProvider */&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;GlobalStyle&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;ThemeProvider&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;Tanto faz a posição do &lt;code&gt;&amp;lt;GlobalStyle /&amp;gt;&lt;/code&gt; dentro do &lt;code&gt;ThemeProvider&lt;/code&gt;, o importante é que &lt;code&gt;&amp;lt;GlobalStyle /&amp;gt;&lt;/code&gt; esteja dentro do scopo do &lt;code&gt;ThemeProvider&lt;/code&gt;, senão o &lt;code&gt;&amp;lt;GlobalStyle /&amp;gt;&lt;/code&gt; não terá acesso as variáveis do nosso tema.&lt;/p&gt;

&lt;p&gt;Acessando a aplicação, podemos ver os estilos globais sendo aplicados, como o background na cor cinza:&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%2F5vgrj2g9hxfbogvcmz4l.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%2F5vgrj2g9hxfbogvcmz4l.png" alt="aplicação com fundo na cor cinza" width="800" height="176"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;commit: &lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/313155a3fe789866559634046530725fcd102a09" rel="noopener noreferrer"&gt;feat: ✨ add global styles&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2.8 Cores e Fonte &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Para este projeto foi escolhido a fonte &lt;a href="https://fonts.google.com/specimen/Roboto" rel="noopener noreferrer"&gt;Roboto&lt;/a&gt; e a fonte &lt;a href="https://fonts.google.com/specimen/Roboto+Mono?query=roboto+mono" rel="noopener noreferrer"&gt;Roboto Mono&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A fonte &lt;code&gt;Roboto Mono&lt;/code&gt; é uma fonte tipográfica monoespaçada, cujas letras e caracteres ocupam o mesmo espaço horizontal. Ela será ideal para ser usada no timer.&lt;/p&gt;

&lt;p&gt;Adicionamos as fontes no arquivo &lt;code&gt;index.html&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!doctype html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"pt"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- adicione essas duas linhas --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"preconnect"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://fonts.googleapis.com"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"preconnect"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://fonts.gstatic.com"&lt;/span&gt; &lt;span class="na"&gt;crossorigin&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- o ideal é deixar os dois links acima por primeiro para carregar mais rápido as fontes --&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- e adicione também esta linha --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,700;1,700&amp;amp;family=Roboto:wght@400;700&amp;amp;display=swap"&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Ignite Timer&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No arquivo de estilos globais &lt;code&gt;src/styles/global.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createGlobalStyle&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GlobalStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createGlobalStyle&lt;/span&gt;&lt;span class="s2"&gt;`
  * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
  }

  body {
    background: #333;
    color: #FFF;
  }

  /* adicione */
  body, input, textarea, button {
    font-family: 'Roboto', sans-serif;
    font-weight: 400;
    font-size: 1rem;
  }
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fonte tipográfica definida, agora vamos definir as cores no nosso tema, no arquivo &lt;code&gt;src/styles/themes/default.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;defaultTheme&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;white&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#FFF&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;gray-100&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;#E1E1E6&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;gray-300&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;#C4C4CC&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;gray-400&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;#8D8D99&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;gray-500&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;#7C7C8A&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;gray-600&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;#323238&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;gray-700&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;#29292E&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;gray-800&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;#202024&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;gray-900&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;#121214&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;green-300&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;#00B37E&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;green-500&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;#00875F&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;green-700&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;#015F43&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;red-500&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;#AB222E&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;red-700&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;#7A1921&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;yellow-500&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;#FBA94C&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;Vamos utilizar as cores no arquivo &lt;code&gt;src/styles/global.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createGlobalStyle&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GlobalStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createGlobalStyle&lt;/span&gt;&lt;span class="s2"&gt;`
  * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
  }

  :focus {
    outline: none;
    box-shadow: 0 0 0 2px &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;green-500&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;;
  }

  body {
    background: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gray-900&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;;
    color: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gray-300&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;;
  }

  body, input, textarea, button {
    font-family: 'Roboto', sans-serif;
    font-weight: 400;
    font-size: 1rem;
  }
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ao digitar &lt;code&gt;props.theme.&lt;/code&gt;, por causa da tipagem, temos todas as cores disponiveis no autocomplete:&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%2Fp6bgxrcwetcrpuzehlk5.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%2Fp6bgxrcwetcrpuzehlk5.png" alt="autocomplete das cores no arquivo global.ts" width="800" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pra finalizar essa parte de cores, precisamos arrumar o erro no arquivo de estilos do botão &lt;code&gt;src/components/Button.styles.ts&lt;/code&gt;:&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%2Fk6mpl00g2suibh7a29vy.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%2Fk6mpl00g2suibh7a29vy.png" alt="erro em props.theme.primary" width="725" height="125"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Trocamos de &lt;code&gt;props.theme.primary&lt;/code&gt; para &lt;code&gt;props.theme["green-500"]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Feito isso já podemos fisualizar o novo estilo:&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%2Fie6u9rfb3gg1tttwi4fr.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%2Fie6u9rfb3gg1tttwi4fr.png" alt="novo estilo" width="800" height="126"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;commit: &lt;a href="https://github.com/maiquitome/rocketseat-project-ignite-timer/commit/c2a5685f22a3332bff3738a0098073dcea119d76" rel="noopener noreferrer"&gt;feat: 💄 add fonts and colors&lt;/a&gt;&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>react</category>
      <category>reactjsdevelopment</category>
      <category>typescript</category>
    </item>
    <item>
      <title>⌨️ 🔍🐛 Corrigindo atalhos no VSCode</title>
      <dc:creator>Dev Maiqui 🇧🇷</dc:creator>
      <pubDate>Sun, 18 Aug 2024 00:00:38 +0000</pubDate>
      <link>https://forem.com/maiquitome/corrigindo-atalhos-no-vscode-4fo7</link>
      <guid>https://forem.com/maiquitome/corrigindo-atalhos-no-vscode-4fo7</guid>
      <description>&lt;p&gt;Ué? Esse atalho não funciona! Será que são outras teclas? 🤔&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%2Fz1hs5qn0wttusypux7ez.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%2Fz1hs5qn0wttusypux7ez.gif" alt="gato nervoso no computador" width="220" height="276"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Eu já me perguntei isso 😁 e tive que fazer várias pesquisas pra solucionar alguns problemas de atalho no VSCode, então nesse artigo eu vou encurtar esse trabalho pra você, bora lá?&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/k_3StV1vWm4"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Capítulos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Plugin do VSCode usando o atalho&lt;/li&gt;
&lt;li&gt;Software do SO usando o atalho&lt;/li&gt;
&lt;li&gt;Atalho do SO&lt;/li&gt;
&lt;li&gt;Conclusão&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Plugin do VSCode usando o atalho &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Vou pegar então um exemplo que aconteceu comigo...&lt;/p&gt;

&lt;p&gt;Existe um atalho para selecionar a linha inteira, &lt;code&gt;⌘ cmd&lt;/code&gt; + &lt;code&gt;L&lt;/code&gt; no mac, e &lt;code&gt;ctrl&lt;/code&gt; + &lt;code&gt;L&lt;/code&gt; no Linux e Windows. Mas por algum motivo não funcionava.&lt;/p&gt;

&lt;p&gt;Então comecei a investigação... 🕵️‍♂️ Primeiro eu precisava descobrir qual o nome desse atalho. Nos links oficiais a seguir você encontra o nome ao lado das teclas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://code.visualstudio.com/shortcuts/keyboard-shortcuts-macos.pdf" rel="noopener noreferrer"&gt;MacOS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://code.visualstudio.com/shortcuts/keyboard-shortcuts-windows.pdf" rel="noopener noreferrer"&gt;Windows&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://code.visualstudio.com/shortcuts/keyboard-shortcuts-linux.pdf" rel="noopener noreferrer"&gt;Linux&lt;/a&gt;&lt;/li&gt;
&lt;/ul&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%2Fktx3k4862wji2y7nuchj.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%2Fktx3k4862wji2y7nuchj.png" alt="encontrando o nome" width="572" height="229"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OK! agora eu sei que &lt;code&gt;Select current line&lt;/code&gt; é o nome que está no link oficial.&lt;/p&gt;

&lt;p&gt;Vamos então ver o que está no VSCode abrindo a janela de atalhos:&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%2F8i2d7w955ic9h1t4zh1t.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%2F8i2d7w955ic9h1t4zh1t.png" alt="como acessar a opção de atalhos" width="344" height="297"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E digitando &lt;code&gt;Select current line&lt;/code&gt;:&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%2F89i9hhnj2pd7okjvac1j.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%2F89i9hhnj2pd7okjvac1j.png" alt="digitando o nome do atalho" width="800" height="274"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Por algum motivo não apareceu nenhum atalho ou opção para adicionar ele no meu VSCode. Normalmente o nome que está na documentação dá certo. Um exemplo: para deletar a linha inteira o nome do atalho é &lt;code&gt;Delete line&lt;/code&gt;:&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%2Fs2bt7ailtd2xmpfhn2n0.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%2Fs2bt7ailtd2xmpfhn2n0.png" alt="digitando  raw `delete line` endraw " width="800" height="227"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Quem sabe então existe outro nome para ele? pode ser!!! existe uma outra forma que podemos pesquisar o atalho:&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%2Fn7jl8h1vu6u6l39p3obg.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%2Fn7jl8h1vu6u6l39p3obg.png" alt="mostrando o ícone de teclado" width="800" height="160"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Na imagem acima você precisa clicar no ícone de teclado. Após isso, qualquer tecla que você digitar, o VSCode irá pesquisar se existe algum atalho registrado, então vamos digitar as teclas do nosso atalho:&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%2Figy13oq2sbcyiajstkpz.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%2Figy13oq2sbcyiajstkpz.png" alt="digitando o atalho" width="800" height="217"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Olha só!!! Não é que o nome está diferente mesmo!!! O atalho &lt;code&gt;⌘ cmd&lt;/code&gt; + &lt;code&gt;L&lt;/code&gt; está gravado para o comando chamado &lt;code&gt;Expand Line Selection&lt;/code&gt;. Mas será que esse comando tem a função mesmo de selecionar toda a linha? Enquanto eu me perguntava isso notei ali que existia dois atalhos do &lt;code&gt;Live Server&lt;/code&gt; (Plugin do VSCode que eu instalei pra fazer o reload automaticamente dos projetos simples de frontend).&lt;/p&gt;

&lt;p&gt;Atalhos esses que precisam de combinação. Quando eu digito o atalho &lt;code&gt;⌘ cmd&lt;/code&gt; + &lt;code&gt;L&lt;/code&gt; uma mensagem aparece no VSCode:&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%2F87p8w2yzypglm00stvgi.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%2F87p8w2yzypglm00stvgi.png" alt="Atalhos que precisam de combinação" width="800" height="179"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💡 Bingo!!! Era isso!!! O Live Server adicionou teclas de atalho que precisavam iniciar com o atalho &lt;code&gt;⌘ cmd&lt;/code&gt; + &lt;code&gt;L&lt;/code&gt;. Quando eu digitava o atalho o VSCode esperava o próximo comando ao invés de selecionar a linha.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Como solucionar?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Podemos clicar com o botão direito do mouse em cima do atalho do Live Server e remover ele, ou editar clicando na lápis, mas você vai precisar escolher um atalho que não entre em conflito com outro.&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%2Ffx4j5udlrpnw2f6ck9vi.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%2Ffx4j5udlrpnw2f6ck9vi.png" alt="removendo o atalho" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bom, agora você aprendeu também que pode editar colocando teclas diferentes para qualquer atalho. Isso é interessante quando você está acostumado com outras teclas.&lt;/p&gt;




&lt;h2&gt;
  
  
  Software do SO usando o atalho &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Outro exemplo que aconteceu comigo foi com o atalho de parar a execução do servidor no terminal, as teclas &lt;code&gt;Ctrl&lt;/code&gt; + &lt;code&gt;c&lt;/code&gt; simplesmente param de funcionar. Após investigação descobri que o software que eu havia instalado para desenhar na tela estava usando esse atalho e, para solucionar, desmarquei esse atalho. Já aproveitei e tudo que estava usando &lt;code&gt;Ctrl&lt;/code&gt; + &lt;code&gt;Outra tecla&lt;/code&gt; alterei para &lt;code&gt;Ctrl&lt;/code&gt; + &lt;code&gt;Shift&lt;/code&gt; + &lt;code&gt;Outra tecla&lt;/code&gt;:&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%2Fqgxruk9o3orhbhe8vemk.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%2Fqgxruk9o3orhbhe8vemk.png" alt="Image description" width="660" height="696"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Atalho do SO &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Outro exemplo que aconteceu comigo foi com o atalho &lt;code&gt;Trigger Suggest&lt;/code&gt;. Eu usava as teclas &lt;code&gt;Ctrl&lt;/code&gt; + &lt;code&gt;Space&lt;/code&gt; tanto no Windows como no Linux mas, quando mudei para o Mac, simplesmente não funcionava, então acabei usando as teclas &lt;code&gt;⌥ Option (alt)&lt;/code&gt; + &lt;code&gt;Escape&lt;/code&gt;, que era uma alternativa já configurada como mostra na imagem abaixo:&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%2Fvh1axp7ezglsh0rj2n8z.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%2Fvh1axp7ezglsh0rj2n8z.png" alt="Image description" width="723" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Até eu tinha me adaptado com essas novas teclas, mas as teclas &lt;code&gt;⌃ Ctrl&lt;/code&gt; + &lt;code&gt;Space&lt;/code&gt; pra mim fazia mais sentido, porque era mais fácil de acessar, então resolvi fazer a investigação até que consegui resolver desmarcando o atalho que o Mac já estava usando como mostra na imagem abaixo:&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%2Fmm7zw5dyfxx06zzqez4v.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%2Fmm7zw5dyfxx06zzqez4v.png" alt="control + space" width="717" height="792"&gt;&lt;/a&gt;&lt;/p&gt;




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

&lt;p&gt;Então quando algum atalho não tiver funcionando no VSCode, ele pode já estar sendo usado dentro do VSCode por algum plugin, pode já estar sendo usado por algum software que você instalou no Sistema Operacional (SO), ou pode já estar sendo usado pelo próprio SO. E, para solucionar, você vai precisar alterar ou remover esse atalho na origem. &lt;/p&gt;

&lt;p&gt;Era isso, espero ter ajudado e obrigado por ler 🙂🙏&lt;/p&gt;




&lt;p&gt;&lt;a href="https://go.hotmart.com/R93865620U" rel="noopener noreferrer"&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%2Fpkoqkmh9hic17tnddjf6.png" alt="A Jornada do Autodidata em Inglês" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>vscode</category>
    </item>
    <item>
      <title>🎲 Criando um Dado com Flexbox e CSS Grid Layout</title>
      <dc:creator>Dev Maiqui 🇧🇷</dc:creator>
      <pubDate>Fri, 05 Jul 2024 22:14:37 +0000</pubDate>
      <link>https://forem.com/maiquitome/criando-um-dado-com-flexbox-e-css-grid-layout-3pl1</link>
      <guid>https://forem.com/maiquitome/criando-um-dado-com-flexbox-e-css-grid-layout-3pl1</guid>
      <description>&lt;p&gt;Quando nos deparamos com uma necessidade de posicionamento usando CSS logo nos perguntamos - Será que eu uso Flexbox ou CSS Grid Layout? Qual a melhor abordagem para esse caso? Neste artigo vamos trazer três abordagens diferentes para posicionar os pontos das seis faces de um dado. A primeira abordagem será com Flexbox e, as outras duas, com CSS Grid Layout.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/maiquitome/creating-dice-using-css-grid-and-flexbox.git" rel="noopener noreferrer"&gt;🔗 Acesse aqui o código no Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Veja o projeto funcionando:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://maiquitome.github.io/creating-dice-using-css-grid-and-flexbox/flexbox/" rel="noopener noreferrer"&gt;🔗 flexbox&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://maiquitome.github.io/creating-dice-using-css-grid-and-flexbox/grid-template-areas/" rel="noopener noreferrer"&gt;🔗 grid-template-areas&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://maiquitome.github.io/creating-dice-using-css-grid-and-flexbox/grid-rows-and-grid-columns/" rel="noopener noreferrer"&gt;🔗 grid-rows-and-grid-columns&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://go.hotmart.com/R93865620U" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpkoqkmh9hic17tnddjf6.png" alt="A Jornada do Autodidata em Inglês" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Criando o arquivo &lt;code&gt;main.css&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
Exemplo com Flexbox

&lt;ul&gt;
&lt;li&gt;Criando a primeira face&lt;/li&gt;
&lt;li&gt;Criando a segunda face&lt;/li&gt;
&lt;li&gt;Criando a terceira face&lt;/li&gt;
&lt;li&gt;Criando a quarta face&lt;/li&gt;
&lt;li&gt;Criando a quinta face&lt;/li&gt;
&lt;li&gt;Criando a sexta face&lt;/li&gt;
&lt;li&gt;Centralizando tudo na tela&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Exemplo com Grid Template Areas

&lt;ul&gt;
&lt;li&gt;Posicionando os Pontos&lt;/li&gt;
&lt;li&gt;Usando &lt;code&gt;grid-template-areas&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Usando &lt;code&gt;grid-area&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Centralizando os pontos nas células&lt;/li&gt;
&lt;li&gt;Mas ainda estou enxergando um problema&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Exemplo com Grid Rows e Grid Columns

&lt;ul&gt;
&lt;li&gt;Entendendo como funciona: &lt;code&gt;grid-row&lt;/code&gt; e &lt;code&gt;grid-column&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Posicionando os pontos&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Considerações finais&lt;/li&gt;

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

&lt;/ul&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/_rdeC6r-bRA"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Criando o arquivo &lt;code&gt;main.css&lt;/code&gt; &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Na raiz do projeto crie o arquivo &lt;code&gt;main.css&lt;/code&gt;. Nele vamos colocar os estilos que servirão tanto para o exemplo do &lt;code&gt;flexbox&lt;/code&gt; quanto para os exemplos com &lt;code&gt;CSS Grid Layout&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Vamos construir o quadrado que servirá para todas as faces do dado. Para isso, selecionaremos todos os elementos &lt;code&gt;div&lt;/code&gt; com o atributo &lt;code&gt;class&lt;/code&gt; cujo valor termina com a string &lt;code&gt;face&lt;/code&gt;. E com a classe &lt;code&gt;.pip&lt;/code&gt; vamos construir cada ponto.&lt;/p&gt;

&lt;p&gt;Em &lt;code&gt;main.css&lt;/code&gt; adicione:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#1b2231&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;class&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"face"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;104px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;104px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#54c59f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.pip&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;24px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;24px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#080a16&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Exemplo com Flexbox &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Vamos começar criando o arquivo HTML. Crie um diretório chamado &lt;code&gt;flexbox/index.html&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F89ve6ip9s6b3rbnrdmm6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F89ve6ip9s6b3rbnrdmm6.png" alt="Criando os diretórios" width="265" height="134"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E vamos importar o &lt;code&gt;main.css&lt;/code&gt;. No arquivo &lt;code&gt;flexbox/index.html&lt;/code&gt; adicione:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"../main.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Criando a primeira face (Flexbox) &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;No arquivo &lt;code&gt;flexbox/index.html&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"../main.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- adicione: --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"first-face"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O resultado será um &lt;strong&gt;quadrado verde&lt;/strong&gt; com uma &lt;strong&gt;cor escura de background&lt;/strong&gt; e um &lt;strong&gt;círculo escuro&lt;/strong&gt; na parte superior do quadrado:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbma53xude1nq2gom1r2l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbma53xude1nq2gom1r2l.png" alt="Quadrado verde com um ponto" width="800" height="210"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Centralizando o ponto
&lt;/h4&gt;

&lt;p&gt;No arquivo &lt;code&gt;flexbox/index.html&lt;/code&gt; adicione:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"../main.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- adicione: --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"style.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; 
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"first-face"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Crie o arquivo &lt;code&gt;flexbox/style.css&lt;/code&gt;. A primeira etapa é informar ao navegador para tornar &lt;code&gt;.first-face&lt;/code&gt; um contêiner flexbox.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.first-face&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&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;Olhando não há grandes alterações, mas por debaixo dos panos com &lt;code&gt;display: flex&lt;/code&gt; podemos usar as linhas &lt;code&gt;MAIN AXIS&lt;/code&gt; e &lt;code&gt;CROSS AXIS&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F67att1gt746370xtii0p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F67att1gt746370xtii0p.png" alt="MAIN AXIS VS CROSS AXIS" width="304" height="261"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O contêiner &lt;code&gt;first-face&lt;/code&gt; agora tem um eixo principal (main axis) horizontal. O eixo principal de um contêiner flexbox que pode ser horizontal ou vertical, mas o &lt;strong&gt;padrão é horizontal&lt;/strong&gt;. Se adicionarmos outro &lt;code&gt;pip&lt;/code&gt; à &lt;code&gt;first-face&lt;/code&gt;, ele aparecerá à direita do primeiro. O contêiner também tem um eixo transversal (cross axis) vertical. O eixo transversal é sempre perpendicular ao eixo principal.&lt;/p&gt;

&lt;p&gt;A propriedade &lt;code&gt;justify-content&lt;/code&gt; define o alinhamento ao longo do &lt;strong&gt;eixo principal (main axis)&lt;/strong&gt;. Como queremos centralizar o &lt;code&gt;pip&lt;/code&gt; ao longo do &lt;strong&gt;eixo principal&lt;/strong&gt;, usaremos o valor &lt;code&gt;center&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;No arquivo &lt;code&gt;flexbox/style.css&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.first-face&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* adicione */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvt4w9vung654db57v4mf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvt4w9vung654db57v4mf.png" alt="justify-content: center" width="411" height="308"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A propriedade &lt;code&gt;align-items&lt;/code&gt; determina como os itens são dispostos ao longo do &lt;strong&gt;eixo transversal (cross axis)&lt;/strong&gt;. Como queremos que o &lt;code&gt;pip&lt;/code&gt; seja centralizado ao longo desse eixo, usaremos o valor &lt;code&gt;center&lt;/code&gt; aqui também.&lt;/p&gt;

&lt;p&gt;No arquivo &lt;code&gt;flexbox/style.css&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.first-face&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* adicione */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5u5no1fcohd4dbfl8h1w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5u5no1fcohd4dbfl8h1w.png" alt="align-items: center" width="434" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Criando a segunda face (Flexbox) &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;No arquivo &lt;code&gt;flexbox/index.html&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"../main.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"style.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"first-face"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- adicione: --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"second-face"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7amlt4frb1xwmrctqdca.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7amlt4frb1xwmrctqdca.png" alt="Adicionando a classe " width="800" height="305"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No arquivo &lt;code&gt;flexbox/style.css&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.first-face&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* adicione */&lt;/span&gt;
&lt;span class="nc"&gt;.second-face&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl4nt94svr1kn6xmb7euo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl4nt94svr1kn6xmb7euo.png" alt="Adicionando " width="800" height="308"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora os dois pontos estão um do lado do outro. Desta vez, queremos que os pontos fiquem em lados opostos do dado. Há um valor para &lt;code&gt;justify-content&lt;/code&gt; que nos permitirá fazer exatamente isso: &lt;code&gt;space-between&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A propriedade &lt;code&gt;space-between&lt;/code&gt; preenche uniformemente o espaço entre os itens flexíveis (flex items). Como há apenas dois pontos, isso os afasta um do outro.&lt;/p&gt;

&lt;p&gt;No arquivo &lt;code&gt;flexbox/style.css&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.first-face&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.second-face&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;space-between&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* adicione */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fduzlmlzeqpm4t3nabiki.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fduzlmlzeqpm4t3nabiki.png" alt="Colocando o " width="800" height="304"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;É aqui que nos deparamos com um problema. Ao contrário de antes, não podemos definir &lt;code&gt;align-items&lt;/code&gt; porque isso afetará os dois pontos. Felizmente, o flexbox inclui &lt;code&gt;align-self&lt;/code&gt;. Essa propriedade nos permite alinhar itens individuais em um contêiner flexível ao longo do eixo transversal da maneira que quisermos! O valor que queremos para essa propriedade é &lt;code&gt;flex-end&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;No arquivo &lt;code&gt;flexbox/style.css&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.first-face&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.second-face&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;space-between&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* adicione */&lt;/span&gt;
&lt;span class="nc"&gt;.second-face&lt;/span&gt; &lt;span class="nc"&gt;.pip&lt;/span&gt;&lt;span class="nd"&gt;:nth-of-type&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;align-self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex-end&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 pseudo-classe CSS &lt;code&gt;:nth-of-type()&lt;/code&gt; corresponde a um ou mais elementos de um dado tipo, baseado em sua posição entre um grupo de irmãos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9fngc56daljzmhzgu7es.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9fngc56daljzmhzgu7es.png" alt="Adicionando " width="800" height="309"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Criando a terceira face (Flexbox) &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;No arquivo &lt;code&gt;flexbox/index.html&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"../main.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"style.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"first-face"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"second-face"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- adicione: --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"third-face"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No arquivo &lt;code&gt;flexbox/style.css&lt;/code&gt; adicione:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.third-face&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;space-between&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.third-face&lt;/span&gt; &lt;span class="nc"&gt;.pip&lt;/span&gt;&lt;span class="nd"&gt;:nth-of-type&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;align-self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.third-face&lt;/span&gt; &lt;span class="nc"&gt;.pip&lt;/span&gt;&lt;span class="nd"&gt;:nth-of-type&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;align-self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex-end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flv0uv7gd15p0gr6unkdq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flv0uv7gd15p0gr6unkdq.png" alt="Adicionando a classe " width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Criando a quarta face (Flexbox) &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Nesta face do dado precisaremos de duas colunas para fazer o posicionamento usando &lt;code&gt;justify-content&lt;/code&gt; tanto na horizontal com na vertical:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpf3z2auj5urrne37woeb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpf3z2auj5urrne37woeb.png" alt="quatro pontos separados por duas colunas" width="583" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Adicione no arquivo &lt;code&gt;flexbox/index.html&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"fourth-face"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- note aqui a classe column --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"column"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- e aqui também colocamos a classe column --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"column"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No arquivo &lt;code&gt;flexbox/style.css&lt;/code&gt; adicione:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.fourth-face&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;space-between&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F13becp0ezhen53tke9ag.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F13becp0ezhen53tke9ag.png" alt="duas colunas com dois pontos juntos cada" width="157" height="148"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No arquivo &lt;code&gt;flexbox/style.css&lt;/code&gt; vamos setar o display como flex:&lt;/p&gt;

&lt;p&gt;Ainda no arquivo &lt;code&gt;flexbox/style.css&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.fourth-face&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;space-between&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* aqui colocamos display como flex */&lt;/span&gt;
&lt;span class="nc"&gt;.fourth-face&lt;/span&gt; &lt;span class="nc"&gt;.column&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flx829a8jgpug751iw4v8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flx829a8jgpug751iw4v8.png" alt="quatro pontos em linha" width="182" height="145"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cada &lt;code&gt;column&lt;/code&gt; possuí dois pontos cada. Podemos usar a propriedade &lt;code&gt;flex-direction&lt;/code&gt; para definir a direção do eixo principal (main axis) como coluna.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.fourth-face&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;space-between&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.fourth-face&lt;/span&gt; &lt;span class="nc"&gt;.column&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* adicione */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F13becp0ezhen53tke9ag.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F13becp0ezhen53tke9ag.png" alt="duas colunas com dois pontos juntos cada" width="157" height="148"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As colunas agora são contêineres flexíveis. Percebeu como colocamos um contêiner flexível diretamente dentro de outro contêiner flexível? Não tem problema! O Flexbox não se importa se os contêineres estão aninhados.&lt;/p&gt;

&lt;p&gt;A etapa final é espaçar os pontos dentro das colunas, separando-os uns dos outros. Como o eixo principal (main axis) agora é vertical, podemos usar o &lt;code&gt;justify-content&lt;/code&gt; novamente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.fourth-face&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;space-between&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.fourth-face&lt;/span&gt; &lt;span class="nc"&gt;.column&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;space-between&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* adicione */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora temos perfeitamente quatro faces do dado:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhfst5oa4ypjxk1wbv8vs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhfst5oa4ypjxk1wbv8vs.png" alt="perfeitamente quatro faces do dado" width="800" height="557"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Criando a quinta face (Flexbox) &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;A quinta face vai ser parecida com o quarta face, mas com uma &lt;code&gt;column&lt;/code&gt; a mais:&lt;/p&gt;

&lt;p&gt;Adicione no arquivo &lt;code&gt;flexbox/index.html&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"fifth-face"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"column"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"column"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"column"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9lobs113m9lhw9y3nhk1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9lobs113m9lhw9y3nhk1.png" alt="Adicionando " width="152" height="181"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Adicione no arquivo &lt;code&gt;flexbox/style.css&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.fifth-face&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;space-between&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;Perceba bem as três colunas definidas:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3fffndi49nt17ptu4290.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3fffndi49nt17ptu4290.png" alt="Adicioando  raw `fifth-face` endraw  no arquivo css" width="166" height="158"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vamos transformar cada coluna em flex e alterar a direção da main axis para poder usar o &lt;code&gt;justify-content&lt;/code&gt; na vertical.&lt;/p&gt;

&lt;p&gt;No arquivo &lt;code&gt;flexbox/style.css&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.fifth-face&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;space-between&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Adicione: */&lt;/span&gt;
&lt;span class="nc"&gt;.fifth-face&lt;/span&gt; &lt;span class="nc"&gt;.column&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;space-between&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5dnl25q8vrqt4ruvzvw9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5dnl25q8vrqt4ruvzvw9.png" alt="Falta centralizar o ponto do meio" width="159" height="148"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Precisamos agora só centralizar o ponto do meio. &lt;/p&gt;

&lt;p&gt;No arquivo &lt;code&gt;flexbox/style.css&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.fifth-face&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;space-between&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.fifth-face&lt;/span&gt; &lt;span class="nc"&gt;.column&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;space-between&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* adicione: */&lt;/span&gt;
&lt;span class="nc"&gt;.fifth-face&lt;/span&gt; &lt;span class="nc"&gt;.column&lt;/span&gt;&lt;span class="nd"&gt;:nth-of-type&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&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 temos perfeitamente cinco faces do dado, faltando apenas a sexta face:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0fzutjy7l2l1du5d5gko.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0fzutjy7l2l1du5d5gko.png" alt="Falta apenas a sexta face" width="800" height="722"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Criando a sexta face (Flexbox) &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Para criar a sexta face do dado ficou fácil, apenas precisamos de duas colunas com três pontos cada.&lt;/p&gt;

&lt;p&gt;Adicione no arquivo &lt;code&gt;flexbox/style.css&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"sixth-face"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"column"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"column"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fab9ad5t5rmwxi5qvrh5c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fab9ad5t5rmwxi5qvrh5c.png" alt="A sexta face apenas com HTML" width="170" height="210"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vamos reaproveitar código. Como a sexta face também possuí apenas duas colunas igual a quarta face, podemos colocar &lt;code&gt;.sixth-face&lt;/code&gt; junto do código do &lt;code&gt;.fourth-face&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.fourth-face&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nc"&gt;.sixth-face&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;space-between&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.fourth-face&lt;/span&gt; &lt;span class="nc"&gt;.column&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;.sixth-face&lt;/span&gt; &lt;span class="nc"&gt;.column&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;space-between&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 sim, seis faces do dado completas:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjimj6mjo9po7zenyhdws.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjimj6mjo9po7zenyhdws.png" alt="Seis faces completas" width="800" height="795"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Centralizando tudo na tela &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;As facea dos dados ficaram em coluna e, já que aprendemos como funciona o Flexbox, que tal usar no &lt;code&gt;body&lt;/code&gt; também para centralizar tudo?&lt;/p&gt;

&lt;p&gt;Adicione no arquivo &lt;code&gt;main.css&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#1b2231&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&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 temos todas as faces, uma do lado da outra:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4xoeu66edup86yp19cex.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4xoeu66edup86yp19cex.png" alt="Todas as faces do dado - uma do lado da outra" width="800" height="669"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Temos um problema ao dominuir a tela na horizontal, os quadros ficam com tamanhos diferentes:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr4jkd582fuwnf2xlhljs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr4jkd582fuwnf2xlhljs.png" alt="quadros com tamanhos diferentes" width="750" height="885"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vamos colocar um comando para quebrar a linha ao invés de alterar o tamanho dos quadrados:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#1b2231&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;flex-wrap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;wrap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* adicione */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fga1so33garwh9wv4yln6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fga1so33garwh9wv4yln6.png" alt="quebrando a linha ao invés de alterar o tamanho dos quadrados" width="751" height="906"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora vamos começar a centralizar tudo.&lt;/p&gt;

&lt;h4&gt;
  
  
  Centralizando na horizontal (main axis):
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#1b2231&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;flex-wrap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;wrap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* adicione */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv4e5efbicoyrjjjid43t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv4e5efbicoyrjjjid43t.png" alt="Centralizando na horizontal (main axis)" width="749" height="908"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Centralizando na vertical (cross axis):
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#1b2231&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;flex-wrap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;wrap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
  &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* adicione */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbybjqi9md0ihx91fufkl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbybjqi9md0ihx91fufkl.png" alt="Centralizando na vertical (cross axis)" width="748" height="911"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Juntando tudo bem no centro:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#1b2231&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;flex-wrap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;wrap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
  &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
  &lt;span class="nl"&gt;align-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* adicione */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F87bdkq1oaayefwfdfne8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F87bdkq1oaayefwfdfne8.png" alt="Usando " width="751" height="912"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora podemos diminuir a tela tranquilamente que todo conteúdo permanece no centro da tela:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnuc6w8u5eut5vxhgb2oj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnuc6w8u5eut5vxhgb2oj.png" alt="todo conteúdo permanece no centro da tela" width="354" height="911"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Exemplo com Grid Template Areas &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Neste exemplo vamos usar o CSS Grid Layout, já que os pontos de um dado tradicional estão alinhados em &lt;strong&gt;três linhas&lt;/strong&gt; e &lt;strong&gt;três colunas&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Imagine a face de um dado como uma grade 3x3, em que cada célula representa a posição de um ponto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+---+---+---+
| a | b | c |
+---+---+---+
| d | e | f |
+---+---+---+
| g | h | i |
+---+---+---+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para criar uma grade simples de 3 por 3 usando CSS, a única coisa que precisamos fazer é definir um elemento contêiner como &lt;code&gt;display: grid&lt;/code&gt; e informar que queremos três linhas (&lt;code&gt;grid-template-rows: 1fr 1fr 1fr;&lt;/code&gt;) e três colunas (&lt;code&gt;grid-template-columns: 1fr 1fr 1fr;&lt;/code&gt;) de tamanhos iguais.&lt;/p&gt;

&lt;p&gt;Crie o arquivo &lt;code&gt;grid-template-areas/style.css&lt;/code&gt; com o seguinte código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;class&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"face"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;grid-template-rows&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&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 unidade &lt;code&gt;fr&lt;/code&gt; permite definir o tamanho de uma linha ou coluna como uma fração do espaço livre do contêiner da grade; no nosso caso, &lt;strong&gt;queremos um terço do espaço disponível&lt;/strong&gt;, portanto, usamos &lt;code&gt;1fr&lt;/code&gt; três vezes.&lt;/p&gt;

&lt;p&gt;Com isso já podemos perceber os pontos separados por 3 colunas, sendo colocados automaticamente em cada uma das células, da esquerda para a direita:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr85515o9me9vwgpo5pu1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr85515o9me9vwgpo5pu1.png" alt="Todas as faces com pontos separados por 3 colunas" width="487" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Podemos simplificar esse código CSS. Em vez de escrever &lt;code&gt;1fr 1fr 1fr&lt;/code&gt;, podemos usar &lt;code&gt;repeat(3, 1fr)&lt;/code&gt; para repetir a unidade &lt;code&gt;1fr&lt;/code&gt; três vezes. Também usamos a propriedade abreviada &lt;code&gt;grid-template&lt;/code&gt; que define &lt;code&gt;linhas/colunas&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;class&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"face"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;grid-template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&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;É simples construir uma grade 3X3 com &lt;code&gt;grid-template&lt;/code&gt;, &lt;strong&gt;mas ainda não usaremos essa propriedade&lt;/strong&gt;. A seguir usaremos &lt;code&gt;grid-template-areas&lt;/code&gt; sem o &lt;code&gt;grid-template&lt;/code&gt;, assim iremos perceber que precisamos adicionar mais tarde o &lt;code&gt;grid-template&lt;/code&gt; também.&lt;/p&gt;

&lt;p&gt;Crie o arquivo &lt;code&gt;grid-template-areas/index.html&lt;/code&gt; com o seguinte código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"../main.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"style.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"first-face"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"second-face"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"third-face"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"fourth-face"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"fifth-face"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"sixth-face"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fws9ygg92wm16yrhixhcj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fws9ygg92wm16yrhixhcj.png" alt="Faces apenas com HTML" width="504" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No código acima já podemos perceber uma diferença em relação ao exemplo anterior usando Flexbox: Não há classes &lt;code&gt;column&lt;/code&gt;. Então percebemos que o arquivo HTML já está mais simples. Vamos agora partir para o arquivo CSS. &lt;/p&gt;

&lt;p&gt;Crie o arquivo &lt;code&gt;grid-template-areas/style.css&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F584i7zqp8hwccp891tlx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F584i7zqp8hwccp891tlx.png" alt="imagem da estrutura de arquivos do projeto" width="298" height="220"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Posicionando os Pontos &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Agora chegamos ao ponto em que precisamos posicionar os pontos (pips) para cada um dos valores de cada face do dado. Seria bom se os pontos fluíssem automaticamente para as posições corretas na grade para cada valor. Infelizmente, precisaremos definir a posição de cada um dos pontos individualmente.&lt;/p&gt;

&lt;p&gt;Lembra da tabela ASCII no início desse exemplo? Vamos criar algo muito semelhante usando CSS. &lt;strong&gt;Em vez de rotular as células na ordem das linhas, usaremos essa ordem específica&lt;/strong&gt;, de modo que precisaremos apenas de uma quantidade mínima de CSS para corrigir os casos extremos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+---+---+---+
| a |   | c |
+---+---+---+
| e | g | f |
+---+---+---+
| d |   | b |
+---+---+---+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbltzll5ilf21y872t7ua.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbltzll5ilf21y872t7ua.png" alt="tabelas com as letras" width="800" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Duas das células são deixadas vazias, pois nunca são usadas em nossos dados.&lt;/p&gt;

&lt;h4&gt;
  
  
  Usando &lt;code&gt;grid-template-areas&lt;/code&gt; &lt;a&gt;
&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Podemos traduzir esse layout para CSS usando a propriedade mágica &lt;code&gt;grid-template-areas&lt;/code&gt; (que substitui o &lt;code&gt;grid-template&lt;/code&gt; usado acima):&lt;/p&gt;

&lt;p&gt;Adicione no arquivo &lt;code&gt;grid-template-areas/style.css&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;class&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"face"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;grid-template-areas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="s1"&gt;"a . c"&lt;/span&gt;
        &lt;span class="s1"&gt;"e g f"&lt;/span&gt;
        &lt;span class="s1"&gt;"d . b"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxi4d6z6j70695pk03dws.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxi4d6z6j70695pk03dws.png" alt="usando grid-template-areas" width="490" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Portanto, em vez de usar unidades tradicionais para dimensionar nossas linhas e colunas, podemos simplesmente nos referir a cada célula com um nome. A própria sintaxe fornece uma visualização da estrutura da grade, assim como a nossa tabela ASCII. Os nomes são definidos pela propriedade &lt;code&gt;grid-area&lt;/code&gt; do item da grade. Os pontos na coluna do meio significa uma célula vazia.&lt;/p&gt;

&lt;p&gt;Aparentemente, olhando a imagem acima, não houve alterações. Falta agora usarmos o &lt;code&gt;grid-area&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Usando &lt;code&gt;grid-area&lt;/code&gt; &lt;a&gt;
&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Usamos a propriedade &lt;code&gt;grid-area&lt;/code&gt; para dar um nome a esse item da grade. O modelo de grade (acima) pode então fazer referência ao item pelo nome para colocá-lo em uma área específica da grade. A pseudo classe &lt;code&gt;:nth-of-type()&lt;/code&gt; nos permite direcionar cada pip individualmente.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Posicionando a letra &lt;code&gt;b&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Com o código abaixo conseguimos vizualizar onde está o ponto 2:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.pip&lt;/span&gt;&lt;span class="nd"&gt;:nth-of-type&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk5npkvyxd2uxhunelubk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk5npkvyxd2uxhunelubk.png" alt="posição da letra  raw `b` endraw " width="800" height="321"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.pip&lt;/span&gt;&lt;span class="nd"&gt;:nth-of-type&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;grid-area&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;b&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;Resultado após a letra &lt;code&gt;b&lt;/code&gt; ter sido posicionada certa:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkw8ofump6jjlx1385n4o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkw8ofump6jjlx1385n4o.png" alt="resultado após a posição certa do  raw `b` endraw " width="601" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Posicionando a letra &lt;code&gt;c&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8bqv4isqoeoqudp8lv28.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8bqv4isqoeoqudp8lv28.png" alt="posição da letra  raw `c` endraw " width="800" height="313"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.pip&lt;/span&gt;&lt;span class="nd"&gt;:nth-of-type&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;grid-area&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;c&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;Resultado após a letra &lt;code&gt;c&lt;/code&gt; ter sido posicionada certa:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ficniboecbu2r3od3y3p0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ficniboecbu2r3od3y3p0.png" alt="resultado após a posição certa do  raw `c` endraw " width="594" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Posicionando a letra &lt;code&gt;d&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2For1rbeoc05sjioe0odi3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2For1rbeoc05sjioe0odi3.png" alt="posição da letra  raw `d` endraw " width="800" height="306"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.pip&lt;/span&gt;&lt;span class="nd"&gt;:nth-of-type&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;4&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;grid-area&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;d&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;Resultado após a letra &lt;code&gt;d&lt;/code&gt; ter sido posicionada certa:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgazyngryc7nbjqov0dhr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgazyngryc7nbjqov0dhr.png" alt="resultado após a posição certa do  raw `d` endraw " width="603" height="395"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Posicionando a letra &lt;code&gt;e&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5ihho4tjgq5tuvxbqtu0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5ihho4tjgq5tuvxbqtu0.png" alt="posição da letra  raw `e` endraw " width="800" height="323"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.pip&lt;/span&gt;&lt;span class="nd"&gt;:nth-of-type&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;5&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;grid-area&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;e&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;Resultado após a letra &lt;code&gt;e&lt;/code&gt; ter sido posicionada certa:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9flpx4oy0eorrwjo5ez1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9flpx4oy0eorrwjo5ez1.png" alt="resultado após a posição certa do  raw `e` endraw " width="602" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Posicionando a letra &lt;code&gt;f&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgg61ddjxryxze2jantas.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgg61ddjxryxze2jantas.png" alt="posição da letra  raw `f` endraw " width="800" height="320"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.pip&lt;/span&gt;&lt;span class="nd"&gt;:nth-of-type&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;6&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;grid-area&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;f&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;Resultado após a letra &lt;code&gt;f&lt;/code&gt; ter sido posicionada certa:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdyjnhqihqis6vr5mgmk2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdyjnhqihqis6vr5mgmk2.png" alt="resultado após a posição certa do  raw `f` endraw " width="597" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Posicionando a letra &lt;code&gt;g&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnx0wstw3hd2jhyx398eq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnx0wstw3hd2jhyx398eq.png" alt="posição da letra  raw `g` endraw " width="800" height="311"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como você pode ver, os valores 1, 3 e 5 ainda estão incorretos. Devido à ordem das áreas do modelo de grade que escolhemos anteriormente, só precisamos reposicionar o último &lt;code&gt;pip&lt;/code&gt; de cada um desses dados. Para obter o resultado que desejamos, combinamos as pseudo classes &lt;code&gt;:nth-of-type(odd)&lt;/code&gt; e &lt;code&gt;:last-of-type&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.pip&lt;/span&gt;&lt;span class="nd"&gt;:nth-of-type&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;odd&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nd"&gt;:last-of-type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;grid-area&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;g&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;ul&gt;
&lt;li&gt;
&lt;code&gt;:nth-of-type(odd)&lt;/code&gt; = todos os irmãos(ímpar)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;last-of-type&lt;/code&gt; = último irmão&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjnlgkc5dukshcnrzfpr6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjnlgkc5dukshcnrzfpr6.png" alt="explicando irmãos ímpares" width="589" height="395"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Resultado após a letra &lt;code&gt;g&lt;/code&gt; ter sido posicionada certa:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F00xkzj9848jxmcsvux8v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F00xkzj9848jxmcsvux8v.png" alt="resultado após a posição certa do  raw `g` endraw " width="607" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Centralizando os pontos nas células &lt;a&gt;
&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Está estranho, não está? é porque precisamos centralizar os pontos, na imagem abaixo, podemos ver os pontos alinhados a esquerda:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkpt1z5exp5asxv6co17i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkpt1z5exp5asxv6co17i.png" alt="Pontos alinhados a esquerda" width="231" height="227"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No mesmo arquivo &lt;code&gt;grid-template-areas/style.css&lt;/code&gt; vamos adicionar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.pip&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;align-self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;justify-self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fudp18ygrb74dsruaqm14.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fudp18ygrb74dsruaqm14.png" alt="pontos centralizados na célula" width="484" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Mas ainda estou enxergando um problema &lt;a&gt;
&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;O padding em cada face está diferente!!!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa12abek430smgo4ofyot.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa12abek430smgo4ofyot.png" alt="mostrando o padding diferente" width="629" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fihlfiw4x27k5jyrx813v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fihlfiw4x27k5jyrx813v.png" alt="face com 4 pontos" width="184" height="178"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl5f9oau1cdv8mput6b1w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl5f9oau1cdv8mput6b1w.png" alt="face com 5 pontos" width="179" height="178"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora vamos usar &lt;code&gt;grid-template-rows&lt;/code&gt; e &lt;code&gt;grid-template-columns&lt;/code&gt; para deixar as células todas do mesmo tamanho.&lt;/p&gt;

&lt;p&gt;No arquivo &lt;code&gt;grid-template-areas/style.css&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;class&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"face"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;grid-template-rows&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c"&gt;/* adicione */&lt;/span&gt;
  &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c"&gt;/* adicione */&lt;/span&gt;
  &lt;span class="py"&gt;grid-template-areas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="s1"&gt;"a . c"&lt;/span&gt;
    &lt;span class="s1"&gt;"e g f"&lt;/span&gt;
    &lt;span class="s1"&gt;"d . b"&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 sim!!! O resultado ficou perfeito!!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqmifo8wyi6y9swbxbbhd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqmifo8wyi6y9swbxbbhd.png" alt="resultado perfeito" width="489" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpgtdupgjwp9x0s75xca3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpgtdupgjwp9x0s75xca3.png" alt="inspecionando a face 4 - ANTES e DEPOIS" width="533" height="283"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Apenas mas uma melhoria no código. Podemos fazer uma abreviação trocando duas linhas por uma.&lt;/p&gt;

&lt;p&gt;No arquivo &lt;code&gt;grid-template-areas/style.css&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;class&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"face"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;grid-template-rows&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c"&gt;/* remover */&lt;/span&gt;
  &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c"&gt;/* remover */&lt;/span&gt;

  &lt;span class="nl"&gt;grid-template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c"&gt;/* adicionar */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.pip&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;align-self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* remover */&lt;/span&gt;
  &lt;span class="py"&gt;justify-self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* remover */&lt;/span&gt;

  &lt;span class="py"&gt;place-self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* adicionar */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O resultado ficou perfeito mas o código ficou muito complexo. Vamos tentar usar o CSS Grid Layout de outra forma? Vamos ver isso no próximo exemplo...&lt;/p&gt;




&lt;h2&gt;
  
  
  Exemplo com Grid Rows e Grid Columns &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Neste exemplo também vamos usar o CSS Grid Layout com &lt;strong&gt;três linhas&lt;/strong&gt; e &lt;strong&gt;três colunas&lt;/strong&gt;, onde cada célula representa a posição de um ponto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+---+---+---+
| . | . | . |
+---+---+---+
| . | . | . |
+---+---+---+
| . | . | . |
+---+---+---+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Entendendo como funciona: &lt;code&gt;grid-row&lt;/code&gt; e &lt;code&gt;grid-column&lt;/code&gt; &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Antes de montarmos o dado com essa solução, vamos só entender como funciona &lt;code&gt;grid-row&lt;/code&gt; e &lt;code&gt;grid-column&lt;/code&gt;. Essa será uma explicação mais rápida pois existe muita coisa pra aprender sobre o assunto e fugiria do escopo desse artigo.&lt;/p&gt;

&lt;p&gt;Vamos já criar os arquivos:&lt;/p&gt;

&lt;p&gt;No arquivo &lt;code&gt;grid-rows-and-grid-columns/index.html&lt;/code&gt; você pode colocar esse código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"../main.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"style.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"face"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"square"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- square é provisório --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fovdolhk1chfs7cyjsd82.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fovdolhk1chfs7cyjsd82.png" alt="estrutura de pastas" width="300" height="297"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E no arquivo &lt;code&gt;grid-rows-and-grid-columns/style.css&lt;/code&gt; você pode colocar esse código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;class&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"face"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;grid-template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.square&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;grid-column-start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;grid-column-end&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&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 resultado será esse:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F16rqpsl39btcbi7a1h39.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F16rqpsl39btcbi7a1h39.png" alt="face com um quadrado na primeira coluna" width="172" height="158"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Temos um quadrado na primeira linha ocupando um espaço da coluna 1 até a coluna 2.&lt;/p&gt;

&lt;p&gt;Como não definimos uma altura (height) e uma largura (width) para o quadrado, ele acaba ocupando o espaço inteiro da célula:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fftoi5jg43uep6qa7zy1i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fftoi5jg43uep6qa7zy1i.png" alt="ocupando o espaço inteiro da célula" width="186" height="178"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vizualizamos 4 linhas na vertical, então podemos especificar que queremos que o quadrado se estenda até a linha 3:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.square&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;grid-column-start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;grid-column-end&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* altere de 2 para 3 */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foyf2n3vobdyahxrs7hml.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foyf2n3vobdyahxrs7hml.png" alt="quadrado virando um retangulo" width="192" height="183"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Podemos especificar que queremos que o quadrado se estenda até a linha 4. Podemos usar o número &lt;code&gt;4&lt;/code&gt; ou podemos usar &lt;code&gt;-1&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.square&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;grid-column-start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;grid-column-end&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* pode usar 4 ou -1 */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6pcetm24ci17l2pg6igj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6pcetm24ci17l2pg6igj.png" alt="quadrado ocupando 3 colunas" width="181" height="175"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Podemos agora especificar que esses quadrados devem começar na linha 2 horizontal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.square&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;grid-column-start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;grid-column-end&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;grid-row-start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* adicione */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Felgagqliorvwlf1yffhi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Felgagqliorvwlf1yffhi.png" alt="quadrados posicionados na linha 2 vertical" width="183" height="181"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Posicionando os pontos com &lt;code&gt;grid-row&lt;/code&gt; e &lt;code&gt;grid-column&lt;/code&gt; &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Agora sim vamos para a solução. &lt;/p&gt;

&lt;p&gt;No arquivo &lt;code&gt;grid-rows-and-grid-columns/index.html&lt;/code&gt; o código final será esse, ou seja não iremos mais modificar ele:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"../main.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"style.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"first-face"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip center middle"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"second-face"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip right bottom"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"third-face"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip middle center"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip bottom right"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"fourth-face"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip right"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip bottom"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip bottom right"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"fifth-face"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip right"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip middle center"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip bottom"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip bottom right"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"sixth-face"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip right"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip right"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip bottom"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pip bottom right"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fws9ygg92wm16yrhixhcj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fws9ygg92wm16yrhixhcj.png" alt="Faces apenas com HTML" width="504" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E no arquivo &lt;code&gt;grid-rows-and-grid-columns/style.css&lt;/code&gt; você pode colocar esse código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;class&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"face"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;grid-template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.top&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;grid-row-start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.middle&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;grid-row-start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.bottom&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/* grid-row-start: 3; */&lt;/span&gt;
  &lt;span class="py"&gt;grid-row-end&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.left&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;grid-column-start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.center&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;grid-column-start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.right&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/* grid-column-start: 3; */&lt;/span&gt;
  &lt;span class="py"&gt;grid-column-end&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-1&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 resultado está quase o esperado:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7jv4bhjz8bzdb6cb5pqc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7jv4bhjz8bzdb6cb5pqc.png" alt="resultado quase esperado" width="483" height="314"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Preciamos centralizar cada ponto em sua célula:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.pip&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;place-self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&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 o resultado ficou perfeito:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F30byar5gium0scl9plde.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F30byar5gium0scl9plde.png" alt="resultado perfeito" width="489" height="324"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4zfhjf9jhiiyb7b83t1w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4zfhjf9jhiiyb7b83t1w.png" alt="sexta face perfeita" width="183" height="182"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Considerações finais &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Podemos concluir que o código da segunda abordagem com &lt;code&gt;grid-template-areas&lt;/code&gt; ficou mais confuso do que as outras abordagens. Já a última abordagem com &lt;code&gt;grid-rows&lt;/code&gt; e &lt;code&gt;grid-columns&lt;/code&gt; teve menos código CSS e ficou fácil de entender o que acontece, sendo assim mais fácil de dar manutenção, então vamos para o ranking:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🥇 1º Lugar: Exemplo 3 (&lt;code&gt;grid-rows&lt;/code&gt; e &lt;code&gt;grid-columns&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;🥈 2º Lugar: Exemplo 1 (Flexbox)&lt;/li&gt;
&lt;li&gt;🥉 3º Lugar: Exemplo 2 (&lt;code&gt;grid-template-areas&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;




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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://davidwalsh.name/flexbox-dice" rel="noopener noreferrer"&gt;Getting Dicey With Flexbox&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/ekeijl/creating-dice-using-css-grid-j4"&gt;Creating dice using CSS grid&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/HyxtLn8g4qc?si=M4fLtgI0F3ZZIaTu" rel="noopener noreferrer"&gt;[css] Designing Dice using CSS Grid&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Era isso... obrigado por ler e até a próxima 🙂👋&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>css</category>
      <category>flexbox</category>
      <category>grid</category>
    </item>
    <item>
      <title>🔏 Imutabilidade de Atribuição VS Imutabilidade de Valor</title>
      <dc:creator>Dev Maiqui 🇧🇷</dc:creator>
      <pubDate>Fri, 28 Jun 2024 11:34:10 +0000</pubDate>
      <link>https://forem.com/maiquitome/imutabilidade-de-atribuicao-vs-imutabilidade-de-valor-41gj</link>
      <guid>https://forem.com/maiquitome/imutabilidade-de-atribuicao-vs-imutabilidade-de-valor-41gj</guid>
      <description>&lt;p&gt;Sim! Podemos alterar o valor de uma &lt;code&gt;const&lt;/code&gt; quando o tipo de dado atribuído a ela é de um array ou objeto. No código abaixo podemos ver que o valor do array foi modificado. &lt;strong&gt;Isso não é imutabilidade de valor!&lt;/strong&gt;&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%2Fbkhcxgfrw7mujl9y72wt.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%2Fbkhcxgfrw7mujl9y72wt.png" alt="alterando o valor de um array atribuído a uma const" width="520" height="262"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Já no código abaixo podemos ver a &lt;strong&gt;imutabilidade de atribuição&lt;/strong&gt;:&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%2Fw885d26ks3qlpz9k1v97.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%2Fw885d26ks3qlpz9k1v97.png" alt="tentando atribuir outro valor a uma const" width="667" height="544"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vamos entender melhor como isso funciona por debaixo dos panos; sobre imutabilidade no JavaScript e &lt;strong&gt;como evitar&lt;/strong&gt; que um array ou objeto atribuído em uma &lt;code&gt;const&lt;/code&gt; seja alterado.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://go.hotmart.com/R93865620U" rel="noopener noreferrer"&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%2Fpkoqkmh9hic17tnddjf6.png" alt="A Jornada do Autodidata em Inglês" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mutabilidade VS Imutabilidade&lt;/li&gt;
&lt;li&gt;
Data Types

&lt;ul&gt;
&lt;li&gt;O que é Stack?&lt;/li&gt;
&lt;li&gt;O que é Heap?&lt;/li&gt;
&lt;li&gt;Tipos de dados primitivos&lt;/li&gt;
&lt;li&gt;Tipos de dados de referência&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Mutabilidade no JavaScript

&lt;ul&gt;
&lt;li&gt;Como clonar propriedades de objetos&lt;/li&gt;
&lt;li&gt;Usando o Spread Operator&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Imutabilidade no JavaScript&lt;/li&gt;

&lt;li&gt;

Como evitar a mutabilidade de objetos

&lt;ul&gt;
&lt;li&gt;Como usar o método &lt;code&gt;Object.preventExtensions&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Como usar o método &lt;code&gt;Object.seal()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Como usar o método &lt;code&gt;Object.freeze()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Como usar &lt;code&gt;Deep Freeze&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Como evitar a mutabilidade de arrays&lt;/li&gt;

&lt;li&gt;Considerações finais&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/LALVj4MnNkA"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Mutabilidade VS Imutabilidade &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;No JavaScript, diferentes tipos de dados (data types em inglês) têm diferentes comportamentos e locais na memória. Portanto, &lt;strong&gt;para reduzir as chances de ter bugs em seu código&lt;/strong&gt;, você precisa entender o conceito de mutabilidade e imutabilidade em JavaScript.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mutabilidade&lt;/strong&gt; refere-se a tipos de dados que podem ser acessados e alterados após serem criados e armazenados na memória. A &lt;strong&gt;imutabilidade&lt;/strong&gt;, por outro lado, refere-se a tipos de dados que não podem ser alterados após a criação, mas que ainda podem ser acessados na memória.&lt;/p&gt;




&lt;h2&gt;
  
  
  Data Types &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Os tipos de dados (data types em inglês) são categorizados em &lt;strong&gt;tipos primitivos&lt;/strong&gt; e &lt;strong&gt;de referência&lt;/strong&gt; no JavaScript. Antes de explicar essas categorias, vamos dar uma olhada em dois termos importantes relacionados à memória que você precisará conhecer: a &lt;strong&gt;Stack&lt;/strong&gt; e a &lt;strong&gt;Heap&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  O que é a Stack? &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;A Stack (pilha em português) é uma estrutura de dados que obedece ao princípio &lt;strong&gt;Last In First Out (LIFO)&lt;/strong&gt;. Isso significa que o último item a entrar na pilha sai primeiro.&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%2Feaothkf0kxqztfrmvg44.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%2Feaothkf0kxqztfrmvg44.png" alt="Last In First Out (LIFO)" width="350" height="245"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Imagem acima da Wikipédia.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  O que é Heap? &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;O &lt;strong&gt;Heap&lt;/strong&gt; é usado apenas em variáveis do &lt;code&gt;tipo de dados de referência&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;O &lt;strong&gt;Heap&lt;/strong&gt; guarda o &lt;strong&gt;valor real&lt;/strong&gt; atribuído à variável. A variável guarda o endereço de memória do Heap. Quando o valor é atribuído à variável, a variável (armazenando o endereço de memória do Heap) é colocada na pilha por cima, por último.&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%2Feau8oxlkhq8li7t5fjlh.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%2Feau8oxlkhq8li7t5fjlh.png" alt="Exemplo Heap e Stack" width="800" height="248"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Tipos de dados primitivos &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Os tipos de dados primitivos são imutáveis e não são objetos porque não têm propriedades e métodos: &lt;code&gt;string&lt;/code&gt;, &lt;code&gt;number&lt;/code&gt;, &lt;code&gt;BigInt&lt;/code&gt;, &lt;code&gt;boolean&lt;/code&gt;, &lt;code&gt;undefined&lt;/code&gt;, &lt;code&gt;Symbol&lt;/code&gt;, &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;🤔 Espere um minuto, você pode pensar – eu mudo os valores das variáveis ​​primitivas o tempo todo!&lt;/p&gt;

&lt;p&gt;Bem, pode parecer que você está modificando um valor, mas esse não é realmente o caso. Vamos mostrar um exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;greet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;greet&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;, World&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Hello, World&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A primeira linha deste código cria a string &lt;code&gt;Hello&lt;/code&gt; e a atribui à variável &lt;code&gt;greet&lt;/code&gt;. A segunda linha anexa &lt;code&gt;, World&lt;/code&gt; a essa string. Parece que estamos mudando a string &lt;code&gt;greet&lt;/code&gt;, mas o JavaScript não altera a string, em vez disso, ele cria uma nova string.&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%2Fy0usjv8flw8y3bkhqy67.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%2Fy0usjv8flw8y3bkhqy67.png" alt="atribuindo valor a variavel greet" width="800" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Tipos de dados de referência &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Por padrão, os &lt;code&gt;tipos de dados de referência&lt;/code&gt; &lt;strong&gt;são mutáveis&lt;/strong&gt;. Os tipos de dados de referência consistem em &lt;strong&gt;funções&lt;/strong&gt;, &lt;strong&gt;arrays&lt;/strong&gt; e &lt;strong&gt;objetos&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Os &lt;code&gt;tipos de dados de referência&lt;/code&gt; colocam a variável na &lt;strong&gt;stack&lt;/strong&gt;. A variável funciona como um ponteiro que aponta para o objeto localizado na &lt;strong&gt;heap&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A principal diferença entre essas categorias é que os &lt;strong&gt;tipos primitivos são &lt;code&gt;imutáveis&lt;/code&gt;&lt;/strong&gt;, mas os &lt;strong&gt;tipos de referência são &lt;code&gt;mutáveis&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Mutabilidade no JavaScript &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Se um tipo de dado for mutável, significa que você pode alterá-lo. A mutabilidade permite que você modifique os valores existentes sem criar novos valores.&lt;/p&gt;

&lt;p&gt;Para cada &lt;strong&gt;objeto&lt;/strong&gt;, um ponteiro é adicionado à &lt;code&gt;stack&lt;/code&gt;, e esse ponteiro aponta para o &lt;strong&gt;objeto&lt;/strong&gt; no &lt;code&gt;heap&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Veja, por exemplo, o código a seguir:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Mike Shinoda&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;47&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="na"&gt;Hobbies&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;cantar&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;tocar guitarra&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;Na &lt;strong&gt;stack&lt;/strong&gt;, você encontrará &lt;code&gt;person&lt;/code&gt;, que é um ponteiro para o objeto real no &lt;strong&gt;heap&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;person2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;person2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fless9um77fp8vo66fhr4.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%2Fless9um77fp8vo66fhr4.png" alt="person2" width="800" height="631"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Outro ponteiro é colocado na &lt;strong&gt;stack&lt;/strong&gt; quando &lt;code&gt;person&lt;/code&gt; é atribuído a &lt;code&gt;person2&lt;/code&gt;. Agora, &lt;strong&gt;esses ponteiros apontam para um único objeto&lt;/strong&gt; no &lt;strong&gt;heap&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Os dados de referência &lt;strong&gt;não copiam valores&lt;/strong&gt;, mas sim &lt;strong&gt;ponteiros&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;person2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;53&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;person2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fpqrrd93inyzuid4k1sl8.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%2Fpqrrd93inyzuid4k1sl8.png" alt="Alterando a idade" width="770" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alterar a idade de &lt;code&gt;person2&lt;/code&gt; atualiza a idade do objeto &lt;code&gt;person&lt;/code&gt;. Agora você sabe que isso ocorre &lt;strong&gt;porque ambos apontam para o mesmo objeto&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Como clonar propriedades de objetos &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;O método &lt;code&gt;object.assign&lt;/code&gt; copia propriedades de um objeto (a origem) para outro objeto (o destino) e retorna o objeto de destino modificado.&lt;/p&gt;

&lt;p&gt;Veja a seguir a sintaxe:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O método tem dois argumentos, &lt;code&gt;target&lt;/code&gt; e &lt;code&gt;source&lt;/code&gt;. O &lt;code&gt;target&lt;/code&gt; é o objeto que recebe as novas propriedades, enquanto a &lt;code&gt;source&lt;/code&gt; é de onde vêm as propriedades. O &lt;code&gt;target&lt;/code&gt; pode ser um objeto vazio &lt;code&gt;{}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Em uma situação em que o &lt;code&gt;source&lt;/code&gt; e o &lt;code&gt;target&lt;/code&gt; compartilham a mesma chave (key em inglês), o objeto de origem substitui o valor da chave no &lt;code&gt;target&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Mike Shinoda&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;47&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="na"&gt;Hobbies&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;cantar&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;tocar guitarra&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;person2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assign&lt;/span&gt;&lt;span class="p"&gt;({},&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As propriedades do objeto &lt;code&gt;person&lt;/code&gt; foram clonadas em um &lt;code&gt;target&lt;/code&gt; vazio.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;person2&lt;/code&gt; agora tem suas próprias propriedades. Você pode comprovar isso alterando o valor de qualquer uma de suas propriedades. Essa alteração não afetará os valores das propriedades do objeto de &lt;code&gt;person&lt;/code&gt;.&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%2Fdf497nc1hg5cf9eog4n1.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%2Fdf497nc1hg5cf9eog4n1.png" alt="Alterando person2" width="800" height="522"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O valor de &lt;code&gt;person2.age&lt;/code&gt; que foi alterado para 53 não afeta de forma alguma o valor de &lt;code&gt;person.age&lt;/code&gt; porque ambos têm suas próprias propriedades.&lt;/p&gt;

&lt;h3&gt;
  
  
  Usando o Spread Operator &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Esta é a sintaxe do Spread Operator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newObj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usar o operador &lt;code&gt;spread&lt;/code&gt; é bastante simples. Você precisa colocar três pontos &lt;code&gt;...&lt;/code&gt; antes do nome do objeto cujas propriedades você pretende clonar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Mike Shinoda&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;47&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="na"&gt;Hobbies&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;cantar&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;tocar guitarra&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;person2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;person2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;53&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;person2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fv46xqptl1zy70r7gaocv.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%2Fv46xqptl1zy70r7gaocv.png" alt="Usando o Spread Operator" width="765" height="477"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Imutabilidade no JavaScript &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Imutabilidade é o estado em que os valores são imutáveis (ou seja, não podem ser alterados). Um valor é imutável quando é impossível alterá-lo. Os tipos de dados primitivos são imutáveis, como discutimos acima.&lt;/p&gt;

&lt;p&gt;Vamos dar uma olhada em um exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;student1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Maiqui&lt;/span&gt;&lt;span class="dl"&gt;"&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;student2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;student1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No código acima, uma variável chamada &lt;code&gt;student1&lt;/code&gt; foi criada e atribuída a &lt;code&gt;student2&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt; &lt;span class="nx"&gt;student1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Mike&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

 &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;student1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

 &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;student2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A alteração de &lt;code&gt;student1&lt;/code&gt; para &lt;code&gt;Mike&lt;/code&gt; não altera o valor inicial de &lt;code&gt;student2&lt;/code&gt;. Isso prova que, nos tipos de dados primitivos, os valores reais são copiados, portanto, ambos têm seus próprios valores. Na memória &lt;strong&gt;stack&lt;/strong&gt;, &lt;code&gt;student1&lt;/code&gt; e &lt;code&gt;student2&lt;/code&gt; são diferentes.&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%2Fecoar9bhm1efnmvskb6s.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%2Fecoar9bhm1efnmvskb6s.png" alt="Alterando student1" width="405" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;stack&lt;/strong&gt; obedece ao princípio &lt;strong&gt;Last-In-First-Out&lt;/strong&gt; (último a entrar, primeiro a sair). O primeiro item que entra na &lt;strong&gt;stack&lt;/strong&gt; é o último a sair e vice-versa. Assim, acessar aos itens armazenados na &lt;strong&gt;stack&lt;/strong&gt; fica fácil.&lt;/p&gt;




&lt;h2&gt;
  
  
  Como evitar a mutabilidade de objetos &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Até agora, você aprendeu que os &lt;strong&gt;objetos são mutáveis por padrão&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;people&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="na"&gt;person1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Mike&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="na"&gt;person2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Chester&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="na"&gt;person3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Joe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;


   &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;defineProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;people&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;person4&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;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Brad&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;people&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora adicionamos o &lt;code&gt;person4&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Para evitar a mutabilidade do objeto, você pode usar os métodos &lt;code&gt;Object.preventExtensions()&lt;/code&gt;, &lt;code&gt;Object.seal()&lt;/code&gt; e &lt;code&gt;Object.freeze()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Para todos os três métodos, exploraremos a &lt;strong&gt;adição de propriedades&lt;/strong&gt; usando a &lt;code&gt;notação de ponto&lt;/code&gt; e a propriedade &lt;code&gt;define&lt;/code&gt;, a &lt;strong&gt;modificação de propriedades&lt;/strong&gt; usando &lt;code&gt;defineProperty&lt;/code&gt; e a &lt;strong&gt;exclusão de propriedades&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Isso lhe dará uma melhor compreensão dos recursos e das limitações de cada método e, por fim, o ajudará a determinar qual método é mais adequado para um caso de uso específico.&lt;/p&gt;

&lt;p&gt;Portanto, vamos nos aprofundar e explorar esses métodos com mais detalhes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Como usar o método &lt;code&gt;Object.preventExtensions&lt;/code&gt; &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Veja a seguir a sintaxe desse método:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventExtensions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O uso do &lt;code&gt;Object.preventExtensions&lt;/code&gt; &lt;strong&gt;impede que novas propriedades entrem no objeto&lt;/strong&gt;. O objeto não aumenta de tamanho e mantém suas propriedades. &lt;strong&gt;Por padrão, todos os objetos em JavaScript são extensíveis&lt;/strong&gt;. Com esse método, você pode excluir propriedades do seu objeto.&lt;/p&gt;

&lt;h4&gt;
  
  
  Tentando adicionar novas propriedades (&lt;code&gt;Object.preventExtensions&lt;/code&gt;)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;usando a &lt;code&gt;notação de ponto (dot notation)&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;makeNonExtensive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="na"&gt;firstname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Maiqui&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="na"&gt;lastname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Tomé&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventExtensions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;makeNonExtensive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

   &lt;span class="nx"&gt;makeNonExtensive&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;designation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Software Engineer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

   &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;makeNonExtensive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verifique o console - a propriedade &lt;code&gt;designation&lt;/code&gt; não foi adicionada e não há nenhuma mensagem de erro:&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%2Fftjupl96hgwtsmrqfs0k.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%2Fftjupl96hgwtsmrqfs0k.png" alt="usando  raw `dot notation` endraw  em preventExtensions" width="769" height="356"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;usando o método &lt;code&gt;defineProperty&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Aqui está a sintaxe:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;defineProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;descriptor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Veja o que está acontecendo no código acima:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;obj&lt;/code&gt;: O objeto ao qual você deseja adicionar propriedades.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;prop&lt;/code&gt;: Você define o nome da propriedade que deseja adicionar ou alterar. Deve ser uma cadeia de caracteres ou um símbolo&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;descriptor&lt;/code&gt;: você inclui o valor da propriedade.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;makeNonExtensive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="na"&gt;firstname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Maiqui&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="na"&gt;lastname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Tomé&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventExtensions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;makeNonExtensive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

   &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;defineProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;makeNonExtensive&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;age&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;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="p"&gt;})&lt;/span&gt;

   &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;makeNonExtensive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A &lt;strong&gt;adição de novas propriedades&lt;/strong&gt; usando a propriedade &lt;code&gt;define&lt;/code&gt; gera esta mensagem de erro: &lt;code&gt;Uncaught TypeError: Cannot define property age, object is not extensible&lt;/code&gt;&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%2Fhbca3a7scwmze7tis2hb.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%2Fhbca3a7scwmze7tis2hb.png" alt="Usando defineProperty para adicionar" width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Como modificar uma propriedade existente usando &lt;code&gt;defineProperty&lt;/code&gt; (&lt;code&gt;Object.preventExtensions&lt;/code&gt;)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;makeNonExtensive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;firstname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Maiqui&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;lastname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Tomé&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventExtensions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;makeNonExtensive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;defineProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;makeNonExtensive&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;firstname&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;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Mike&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;makeNonExtensive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O valor da propriedade de um objeto não extensível pode ser alterado:&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%2Fuougsvoq80xi7uhjy7j1.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%2Fuougsvoq80xi7uhjy7j1.png" alt="Usando defineProperty para modificar" width="792" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Como excluir uma propriedade (&lt;code&gt;Object.preventExtensions&lt;/code&gt;)
&lt;/h4&gt;

&lt;p&gt;Aqui está a sintaxe:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;delete&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;propertyname&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;makeNonExtensive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="na"&gt;firstname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Maiqui&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="na"&gt;lastname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Tomé&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventExtensions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;makeNonExtensive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;delete&lt;/span&gt; &lt;span class="nx"&gt;makeNonExtensive&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lastname&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;makeNonExtensive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apesar de o objeto não ser extensível, a propriedade &lt;code&gt;lastname&lt;/code&gt; foi excluída:&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%2Fo4tjqbed7pqmkxh857jo.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%2Fo4tjqbed7pqmkxh857jo.png" alt="excluindo uma propriedade" width="623" height="357"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Como usar o método &lt;code&gt;Object.seal()&lt;/code&gt; &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Todos os objetos em Javascript são extensíveis por padrão. Como o nome sugere, esse método &lt;strong&gt;sela&lt;/strong&gt; um objeto. Não é possível adicionar novas propriedades a um objeto selado ou excluir uma propriedade existente de um objeto selado. Mas o &lt;code&gt;object.seal&lt;/code&gt; permite modificar as propriedades existentes.&lt;/p&gt;

&lt;p&gt;Aqui está a sintaxe:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;seal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Como adicionar novas propriedades (&lt;code&gt;Object.seal()&lt;/code&gt;)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;people&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;person1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Maiqui&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;person2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Maria&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="na"&gt;person3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Eduardo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;seal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;people&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="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isSealed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;people&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Object.isSealed(people)&lt;/code&gt; é usado para verificar se um objeto está selado.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Como usar a &lt;code&gt;notação de ponto&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;people&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;person4&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Patrick&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;people&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Sem produzir um erro&lt;/strong&gt;, a &lt;code&gt;notação de ponto&lt;/code&gt; &lt;strong&gt;falha&lt;/strong&gt; ao adicionar a nova propriedade &lt;code&gt;person4&lt;/code&gt;:&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%2Fno5bl4kzr3dmfui0yiex.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%2Fno5bl4kzr3dmfui0yiex.png" alt="people.person4 = " width="800" height="471"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Usando o método &lt;code&gt;defineProperty&lt;/code&gt; (&lt;code&gt;Object.seal()&lt;/code&gt;)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;people&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;person1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Maiqui&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;person2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Maria&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="na"&gt;person3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Eduardo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;seal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;people&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;defineProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;people&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;person4&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;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Patrick&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;people&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A mensagem de erro &lt;code&gt;"Uncaught TypeError: Cannot define property student4, the object is not extendable"&lt;/code&gt; é lançada quando se tenta adicionar a mesma propriedade usando o método &lt;code&gt;defineProperty&lt;/code&gt;.&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%2F019th7avwuzxzncpatrc.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%2F019th7avwuzxzncpatrc.png" alt="Usando o método  raw `defineProperty` endraw " width="800" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Como modificar uma propriedade existente usando &lt;code&gt;defineProperty&lt;/code&gt; (&lt;code&gt;Object.seal()&lt;/code&gt;)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;people&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;person1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Maiqui&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;person2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Maria&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="na"&gt;person3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Eduardo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;seal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;people&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;defineProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;people&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;person2&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;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Maria Clara&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;people&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora, o &lt;code&gt;person2&lt;/code&gt; foi alterado de &lt;code&gt;"Maria"&lt;/code&gt; para &lt;code&gt;"Maria Clara"&lt;/code&gt;:&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%2F9tf4qmlnmpu87vqtkwwh.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%2F9tf4qmlnmpu87vqtkwwh.png" alt="alterando de  raw `" width="800" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Tentando remover uma propriedade existente (&lt;code&gt;Object.seal()&lt;/code&gt;)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;people&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;person1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Maiqui&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;person2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Maria&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="na"&gt;person3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Eduardo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;seal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;people&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;delete&lt;/span&gt; &lt;span class="nx"&gt;people&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;person1&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;people&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As propriedades não podem ser removidas dos objetos selados. No console, &lt;code&gt;person1&lt;/code&gt; ainda permanece:&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%2F0kp2w8bx66ju2m7ts3km.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%2F0kp2w8bx66ju2m7ts3km.png" alt="tentando remover propriedade" width="800" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Como usar o método &lt;code&gt;Object.freeze()&lt;/code&gt; &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Aqui está a sintaxe:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O método &lt;code&gt;Object.freeze()&lt;/code&gt; congela um objeto. O uso desse método &lt;strong&gt;garante alta integridade&lt;/strong&gt; ao assegurar que não será possível extrair, modificar propriedades existentes ou adicionar novas propriedades ao objeto.&lt;/p&gt;

&lt;p&gt;Para verificar se um objeto está congelado, use a sintaxe abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isFrozen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;ATENÇÃO&lt;/strong&gt; 🚨&lt;br&gt;
Mesmo quando você aplica o &lt;code&gt;Object.freeze()&lt;/code&gt; a um objeto, é possível adicionar uma nova propriedade, modificar uma propriedade existente ou excluir propriedades de objetos &lt;strong&gt;aninhados sob ele&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Assim como fizemos com outros métodos, vamos explorar o método &lt;code&gt;Object.freeze()&lt;/code&gt; em relação à adição de novas propriedades, modificação de valores ou exclusão de propriedades de um objeto.&lt;/p&gt;

&lt;h4&gt;
  
  
  Tentando adicionar novas propriedades (&lt;code&gt;Object.freeze()&lt;/code&gt;)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Usando &lt;code&gt;dot notation&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sportClubInternacional&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;player1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Enner Valencia&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;player2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sergio Rochet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="na"&gt;player3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Rafael Borré&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sportClubInternacional&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;sportClubInternacional&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;player4&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Alan Patrick&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sportClubInternacional&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Observe que o &lt;code&gt;player4&lt;/code&gt; não foi adicionado:&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%2Fwcsohttl4xvgwkju7f2b.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%2Fwcsohttl4xvgwkju7f2b.png" alt="sportClubInternacional.player4" width="800" height="294"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Usando o método &lt;code&gt;defineProperty&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sportClubInternacional&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;player1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Enner Valencia&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;player2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sergio Rochet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="na"&gt;player3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Rafael Borré&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sportClubInternacional&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;defineProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sportClubInternacional&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;player4&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;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Alan Patrick&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sportClubInternacional&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A notação de ponto falha silenciosamente ao tentar adicionar uma propriedade, mas &lt;code&gt;defineproperty&lt;/code&gt; gera um &lt;code&gt;TypeError&lt;/code&gt;:&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%2Fx3lj6sonxpmuvzp2uh3x.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%2Fx3lj6sonxpmuvzp2uh3x.png" alt="defineproperty gera um TypeError" width="800" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Tentando modificar propriedades (&lt;code&gt;Object.freeze()&lt;/code&gt;)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sportClubInternacional&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;player1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Enner Valencia&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;player2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sergio Rochet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="na"&gt;player3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Rafael Borré&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sportClubInternacional&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;sportClubInternacional&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;player1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Enner Valencia - Atacante&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sportClubInternacional&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fk4jpnx6smexy7tbcn9lk.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%2Fk4jpnx6smexy7tbcn9lk.png" alt="sportClubInternacional.player1 = " width="800" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O código acima falhou silenciosamente, mas com a propriedade &lt;code&gt;defineProperty&lt;/code&gt; abaixo, um &lt;code&gt;typeError&lt;/code&gt; é lançado.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sportClubInternacional&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;player1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Enner Valencia&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;player2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sergio Rochet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="na"&gt;player3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Rafael Borré&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sportClubInternacional&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;defineProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sportClubInternacional&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;player1&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;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Enner Valencia - Atacante&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sportClubInternacional&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2F0mu0e8pz85orkk94xeyv.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%2F0mu0e8pz85orkk94xeyv.png" alt="Object.defineProperty" width="800" height="421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Tentando deletar propriedades (&lt;code&gt;Object.freeze()&lt;/code&gt;)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sportClubInternacional&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;player1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Enner Valencia&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;player2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sergio Rochet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="na"&gt;player3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Rafael Borré&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sportClubInternacional&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;delete&lt;/span&gt; &lt;span class="nx"&gt;sportClubInternacional&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;player1&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sportClubInternacional&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A tentativa de excluir uma propriedade em um objeto congelado também falha silenciosamente:&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%2Fd2tyypyw0i010fqtjmca.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%2Fd2tyypyw0i010fqtjmca.png" alt="delete sportClubInternacional.player1" width="800" height="272"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Como usar Deep Freeze &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sportClubInternacional&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;player1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Enner Valencia&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;player2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sergio Rochet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="na"&gt;player3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Rafael Borré&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;substitutes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="na"&gt;player4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Lucas Alario&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="na"&gt;player5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Thiago Maia&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="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sportClubInternacional&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;defineProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sportClubInternacional&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;substitutes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;player6&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;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Alan Patrick&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sportClubInternacional&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;code&gt;player6&lt;/code&gt; foi adicionado aos &lt;code&gt;substitutos aninhados&lt;/code&gt;, embora o método &lt;code&gt;Object.freeze()&lt;/code&gt; tenha sido aplicado aos jogadores da equipe principal.&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%2Fxwyqnr69b7uw0gsb7j1s.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%2Fxwyqnr69b7uw0gsb7j1s.png" alt="O player6 foi adicionado" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Deletando o jogador reserva aninhado
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sportClubInternacional&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;player1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Enner Valencia&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;player2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sergio Rochet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="na"&gt;player3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Rafael Borré&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;substitutes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="na"&gt;player4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Lucas Alario&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="na"&gt;player5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Thiago Maia&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="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sportClubInternacional&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;delete&lt;/span&gt; &lt;span class="nx"&gt;sportClubInternacional&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;substitutes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;player5&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sportClubInternacional&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;code&gt;player5&lt;/code&gt; foi removido. Tudo o que o &lt;code&gt;object.freeze&lt;/code&gt; impede no objeto pai pode ser feito no objeto filho que está aninhado:&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%2F5vq74xw8glu964pigkwg.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%2F5vq74xw8glu964pigkwg.png" alt="Deletando o jogador reserva aninhado player5" width="800" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para evitar isso, empregamos a técnica de congelamento profundo (Deep Freeze em inglês), conforme mostrado abaixo:&lt;/p&gt;

&lt;h4&gt;
  
  
  Aplicando o Deep Freeze
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deepVal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prop&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nf"&gt;deepVal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;prop&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="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&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;sportClubInternacional&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;deepVal&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;player1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Enner Valencia&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;player2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sergio Rochet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="na"&gt;player3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Rafael Borré&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;substitutes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="na"&gt;player4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Lucas Alario&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="na"&gt;player5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Thiago Maia&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="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sportClubInternacional&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="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isFrozen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sportClubInternacional&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fzoodg48mtztngbnz5p9r.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%2Fzoodg48mtztngbnz5p9r.png" alt="adicionando deepVal" width="800" height="582"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Tentando adicionar uma nova propriedade ao objeto filho
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deepVal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prop&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nf"&gt;deepVal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;prop&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="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&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;sportClubInternacional&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;deepVal&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;player1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Enner Valencia&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;player2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sergio Rochet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="na"&gt;player3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Rafael Borré&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;substitutes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="na"&gt;player4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Lucas Alario&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="na"&gt;player5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Thiago Maia&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="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sportClubInternacional&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;defineProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sportClubInternacional&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;substitutes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;player6&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;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Alan Patrick&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sportClubInternacional&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora, quando você tentar adicionar uma propriedade, receberá este erro &lt;code&gt;Uncaught TypeError: Cannot define property player6, object is not extensible&lt;/code&gt;:&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%2Fjp90mwu550oysovkuoh5.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%2Fjp90mwu550oysovkuoh5.png" alt="deep freeze funcionando" width="780" height="581"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Além disso, o Deep Freeze também impede que você altere e exclua propriedades de um objeto.&lt;/p&gt;




&lt;h2&gt;
  
  
  Como evitar a mutabilidade de arrays &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;A mutabilidade em arrays segue o mesmo princípio dos objetos. Vou mostrar aqui só um exemplo pois é bem parecido com os exemplos de objetos já que ambos são &lt;code&gt;tipos de dados de referência&lt;/code&gt;:&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%2Fxnefl3mm7w7kz7x5ae81.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%2Fxnefl3mm7w7kz7x5ae81.png" alt="Exemplos com array" width="800" height="649"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Considerações finais &lt;a&gt;
&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Neste artigo você viu sobre os vários tipos de dados e se eles são imutáveis ou mutáveis por padrão.&lt;/p&gt;

&lt;p&gt;Você viu que quando você usa &lt;code&gt;const&lt;/code&gt; você deve se preocupar com os &lt;code&gt;tipos de dados de referencia&lt;/code&gt; que são mutáveis.&lt;/p&gt;

&lt;p&gt;Os objetos podem ser alterados por padrão. Mas o uso de métodos específicos, como &lt;code&gt;Object.seal&lt;/code&gt;, &lt;code&gt;Object.freeze&lt;/code&gt; e &lt;code&gt;preventExtensions&lt;/code&gt;, pode impedir a mutabilidade.&lt;/p&gt;

&lt;p&gt;O nível de imutabilidade fornecido por esses métodos varia, portanto, certifique-se de usar aquele que corresponde ao nível de integridade que você deseja atingir. &lt;/p&gt;

&lt;p&gt;Era isso... obrigado por ler e até a próxima 🙂👋&lt;/p&gt;




&lt;p&gt;Para a construção deste artigo foi utilizado os seguintes conteúdos como base: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.freecodecamp.org/news/mutability-vs-immutability-in-javascript" rel="noopener noreferrer"&gt;Mutability vs Immutability in JavaScript – Explained with Code Examples&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.freecodecamp.org/news/immutability-in-javascript-with-examples" rel="noopener noreferrer"&gt;Immutability in JavaScript – Explained with Examples&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/thecharacterv/defining-primitive-and-non-primitive-data-types-in-javascript-40gk"&gt;Defining Primitive and Non-Primitive Data Types in JavaScript&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.freecodecamp.org/news/primitive-vs-reference-data-types-in-javascript" rel="noopener noreferrer"&gt;Primitive vs Reference Data Types in JavaScript&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>braziliandevs</category>
      <category>imutabilidade</category>
    </item>
    <item>
      <title>🎨 Melhore Seu Tema Favorito no VSCode em Minutos!</title>
      <dc:creator>Dev Maiqui 🇧🇷</dc:creator>
      <pubDate>Fri, 14 Jun 2024 14:50:35 +0000</pubDate>
      <link>https://forem.com/maiquitome/modifique-qualquer-tema-no-vscode-3fch</link>
      <guid>https://forem.com/maiquitome/modifique-qualquer-tema-no-vscode-3fch</guid>
      <description>&lt;p&gt;Se você é uma pessoa como eu era, que mudava de tema a todo momento no VSCode 😅, chegando ao ponto de pensar em criar seu próprio tema, mas desistiu por falta de tempo ou preguiça de colocar tanto esforço nisso, eu tenho uma solução bem mais fácil que vai resolver esse problema!&lt;/p&gt;

&lt;p&gt;Você vai conseguir alterar aquele tema que você gosta, mas acha que poderia ser melhor; assim, não precisará trocar de tema por um bom tempo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://go.hotmart.com/R93865620U" rel="noopener noreferrer"&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%2Fpkoqkmh9hic17tnddjf6.png" alt="A Jornada do Autodidata em Inglês" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para exemplificar vou modificar o &lt;a href="https://marketplace.visualstudio.com/items?itemName=DaltonMenezes.aura-theme" rel="noopener noreferrer"&gt;Aura Theme&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vou escolher o &lt;code&gt;Aura Dark (Soft Text)&lt;/code&gt; que é mais confortável para o olho no meu modelo de monitor.&lt;/p&gt;

&lt;p&gt;Vamos modificar primeiramente as cores do código e depois as cores dos painéis e similares.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/SDC97qQQlCU"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Modificando as cores do código
&lt;/h2&gt;

&lt;p&gt;Link para a documentação oficial dessa parte: &lt;a href="https://code.visualstudio.com/docs/getstarted/themes#_editor-syntax-highlighting" rel="noopener noreferrer"&gt;https://code.visualstudio.com/docs/getstarted/themes#_editor-syntax-highlighting&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No seu VSCode pressione as teclas "shift+cmd+p" (Mac) ou "shift+ctrl+p" (Windows, Linux), digite &lt;code&gt;Preferences: Open User Settings (JSON)&lt;/code&gt; e pressione ENTER.&lt;/p&gt;

&lt;p&gt;Vamos adicionar o seguinte código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;editor.tokenColorCustomizations&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="c1"&gt;// Aqui a mudança afeta todos os temas&lt;/span&gt;
  &lt;span class="c1"&gt;// Para exemplificar, vamos modificar a cor dos comentários para vermelho&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;comments&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;#FF0000&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O código acima modificou a cor dos comentários para todos os temas instalados no seu VSCode, mas podemos modificar apenas para o tema &lt;code&gt;Aura Dark (Soft Text)&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;editor.tokenColorCustomizations&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;[Aura Dark (Soft Text)]&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="c1"&gt;// Aqui a mudança afeta apenas o tema `Aura Dark (Soft Text)`&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;comments&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;#FF0000&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No seu VSCode pressione novamente as teclas "shift+cmd+p" (Mac) ou "shift+ctrl+p" (Windows, Linux), digite &lt;code&gt;Developer: Inspect Editor Tokens and Scopes&lt;/code&gt; e pressione ENTER.&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%2Fiwevfz90ewlnz1evv7nd.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%2Fiwevfz90ewlnz1evv7nd.png" alt="Image description" width="663" height="552"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[Aura Dark (Soft Text)]&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;textMateRules&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&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="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scope&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;variable.other.object.js.jsx&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;settings&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;foreground&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;#C17AC8&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Resultado:&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%2F45sgtvw5zvkzby3w0yf1.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%2F45sgtvw5zvkzby3w0yf1.png" alt="Image description" width="676" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Posso fazer o mesmo com as palavras acima que ainda estão em branco:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;editor.tokenColorCustomizations&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;[Aura Dark (Soft Text)]&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;textMateRules&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&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="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scope&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;variable.other.object.js.jsx&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;variable.other.readwrite.alias.js.jsx&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;// adicione&lt;/span&gt;
          &lt;span class="p"&gt;],&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;settings&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;foreground&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;#C17AC8&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="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;Resultado:&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%2Fdtn6ejuhbsp3dzj6u6wc.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%2Fdtn6ejuhbsp3dzj6u6wc.png" alt="Image description" width="689" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Colocando palavras em itálico
&lt;/h2&gt;

&lt;p&gt;Como eu gosto do itálico da fonte &lt;a href="https://rubjo.github.io/victor-mono/" rel="noopener noreferrer"&gt;Victor Mono&lt;/a&gt; eu vou deixar algumas palavras em itálico:&lt;/p&gt;

&lt;p&gt;No seu VSCode pressione novamente as teclas "shift+cmd+p" (Mac) ou "shift+ctrl+p" (Windows, Linux), digite &lt;code&gt;Developer: Inspect Editor Tokens and Scopes&lt;/code&gt; e pressione ENTER.&lt;/p&gt;

&lt;p&gt;Nesse exemplo vamos colocar a palavra &lt;code&gt;import&lt;/code&gt; em itálico:&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%2Fytb3suamart161gqiu78.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%2Fytb3suamart161gqiu78.png" alt="Image description" width="665" height="495"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[Aura Dark (Soft Text)]&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;textMateRules&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&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;italic&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Coloque um nome que lembre a alteração&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scope&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;keyword.control.import.js.jsx&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;settings&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;fontStyle&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;italic&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Também quero a palavra &lt;code&gt;function&lt;/code&gt; em itálico:&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%2Fg5b7xloo2m02s0yex7ln.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%2Fg5b7xloo2m02s0yex7ln.png" alt="Image description" width="558" height="547"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;editor.tokenColorCustomizations&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;[Aura Dark (Soft Text)]&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;textMateRules&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&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;italic&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;scope&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;keyword.control.import.js.jsx&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;storage.type.function.js.jsx&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;// Adicione&lt;/span&gt;
          &lt;span class="p"&gt;],&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;settings&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;fontStyle&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;italic&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="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Alterando cores dos painéis e similares
&lt;/h2&gt;

&lt;p&gt;Descobrir o nome dos painéis: &lt;a href="https://code.visualstudio.com/api/references/theme-color" rel="noopener noreferrer"&gt;https://code.visualstudio.com/api/references/theme-color&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vamos agora remover a borda da aba selecionada:&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%2F75ximslhndmx8pwdum3j.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%2F75ximslhndmx8pwdum3j.png" alt="Image description" width="800" height="188"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;workbench.colorCustomizations&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;[Aura Dark (Soft Text)][Aura Dark]&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;tab.inactiveBackground&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;#110F18&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;tab.unfocusedActiveBorder&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;#110F18&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;tab.activeBorder&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;#15141B&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;Resultado:&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%2Ff0zfo5j3f4wmrj5qupud.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%2Ff0zfo5j3f4wmrj5qupud.png" alt="Image description" width="565" height="236"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Deixando só a aba selecionada com a mesma cor do background do código (ajuda a identificar melhor qual aba está selecionada):&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%2Fcyx60gjqzna71xinz6xi.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%2Fcyx60gjqzna71xinz6xi.png" alt="Image description" width="800" height="154"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;workbench.colorCustomizations&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;[Aura Dark (Soft Text)][Aura Dark]&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;tab.inactiveBackground&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;#110F18&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;tab.unfocusedActiveBorder&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;#110F18&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;tab.activeBorder&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;#15141B&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;tab.activeBackground&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;#15141B&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// adicione&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;editorGroupHeader.tabsBackground&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;#110F18&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;// adicione&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;Resultado:&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%2Fax0sgidyipbeahnmyfw6.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%2Fax0sgidyipbeahnmyfw6.png" alt="Image description" width="800" height="261"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Alterando a cor da ActivityBar
&lt;/h2&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%2F03v16r76h8izd9hrnodl.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%2F03v16r76h8izd9hrnodl.png" alt="Image description" width="800" height="474"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;workbench.colorCustomizations&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;[Aura Dark (Soft Text)][Aura Dark]&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;tab.inactiveBackground&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;#110F18&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;tab.activeBorder&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;#15141B&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;tab.activeBackground&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;#15141B&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;editorGroupHeader.tabsBackground&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;#110F18&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;activityBar.background&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;#110F18&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;// adicione&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;Resultado:&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%2Fos69335hyjbixgcp7itw.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%2Fos69335hyjbixgcp7itw.png" alt="Image description" width="800" height="604"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Com isso você pode alterar qualquer cor no VSCode, às vezes você pode demorar um pouco para descobrir o nome de certo painel, pois a documentação não é tão clara assim. &lt;/p&gt;

&lt;p&gt;Espero ter ajudado, até a próxima 😀👋&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>tema</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Error Solution: Your enrollment could not be completed.</title>
      <dc:creator>Dev Maiqui 🇧🇷</dc:creator>
      <pubDate>Fri, 22 Dec 2023 01:38:53 +0000</pubDate>
      <link>https://forem.com/maiquitome/error-solution-your-enrollment-could-not-be-completed-4k32</link>
      <guid>https://forem.com/maiquitome/error-solution-your-enrollment-could-not-be-completed-4k32</guid>
      <description>&lt;p&gt;I'm trying to register for the &lt;strong&gt;Apple Developer Program&lt;/strong&gt; but I can't because of this error: &lt;code&gt;Your enrollment could not be completed&lt;/code&gt;. (December 2023). Apple support has told me several times that there's nothing they can do, 4 attendants... terrible service from Apple, how sad.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;An example of Apple's terrible support service:&lt;/strong&gt;&lt;br&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%2Fg192tgte72p0nphkagvc.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%2Fg192tgte72p0nphkagvc.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Solution
&lt;/h1&gt;

&lt;p&gt;1 - Unfortunately, you'll have to create a new Apple ID.&lt;/p&gt;

&lt;p&gt;2 - With your new Apple ID, click on the &lt;code&gt;Continue web registration&lt;/code&gt; link. &lt;strong&gt;Do not&lt;/strong&gt; use the Apple Developer app.&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%2Flw69b8vk055a1jxffsbv.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%2Flw69b8vk055a1jxffsbv.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3 - Follow the next steps until you reach the payment page. Make the payment and wait 48 hours to receive the payment confirmation e-mail&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%2Fea2zrhmd6206y0jujtqp.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%2Fea2zrhmd6206y0jujtqp.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;4 - The payment confirmation didn't arrive in my email, so I called Apple support. They sent me an email with a link to send me my document.&lt;/p&gt;

&lt;p&gt;I hope I've helped :)&lt;/p&gt;

</description>
      <category>apple</category>
      <category>errors</category>
      <category>appledeveloperprogram</category>
    </item>
    <item>
      <title>💧💪 Concorrência em Elixir #1: Módulo Task</title>
      <dc:creator>Dev Maiqui 🇧🇷</dc:creator>
      <pubDate>Sun, 10 Jul 2022 14:49:29 +0000</pubDate>
      <link>https://forem.com/maiquitome/concorrencia-em-elixir-1-modulo-task-28c9</link>
      <guid>https://forem.com/maiquitome/concorrencia-em-elixir-1-modulo-task-28c9</guid>
      <description>&lt;p&gt;Para melhor entendimento desse post, indico a leitura de: &lt;a href="https://bit.ly/3nhnLVh" rel="noopener noreferrer"&gt;Olá mundo da programação concorrente&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Este post é uma tradução da parte que fala sobre o módulo Task do livro &lt;a href="https://bit.ly/3bj0PlM" rel="noopener noreferrer"&gt;Concurrent Data Processing in Elixir&lt;/a&gt; de &lt;a href="https://github.com/svileng" rel="noopener noreferrer"&gt;Svilen Gospodinov&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://go.hotmart.com/R93865620U" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpkoqkmh9hic17tnddjf6.png" alt="A Jornada do Autodidata em Inglês" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Conforme o livro &lt;strong&gt;Concurrent Data Processing in Elixir&lt;/strong&gt;, o processamento de dados é uma parte essencial de muitas aplicações de software. Na verdade, a maioria dos engenheiros nem sequer pensa nisso como algo separado da programação. Mas se você está transformando informações de alguma forma, por exemplo, ao fazer relatórios, agregação de dados ou análises, então você está fazendo processamento de dados.&lt;/p&gt;

&lt;p&gt;Graças à Máquina Virtual Erlang (também conhecida como BEAM), todos que usam Elixir se beneficiam de seu incrível modelo de concorrência, sendo particularmente adequado para tarefas concorrentes de longa duração. Como resultado, você verá que a linguagem Elixir oferece mais maneiras de realizar trabalhos concorrentes do que outras linguagens. &lt;/p&gt;

&lt;p&gt;Embora isto seja uma coisa boa, também pode ser um desafio encontrar a ferramenta certa para o trabalho. Algumas tarefas são uma excelente escolha para &lt;code&gt;Flow&lt;/code&gt;, enquanto outras são perfeitas para &lt;code&gt;Broadway&lt;/code&gt;. Às vezes é mais fácil usar apenas o &lt;code&gt;GenStage&lt;/code&gt;, ou mesmo o módulo &lt;code&gt;Task&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;As técnicas certas o ajudarão a simplificar seu produto, melhorar o desempenho de seu código e tornar sua aplicação mais resistente a erros e ao aumento da carga de trabalho.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Introdução&lt;/li&gt;
&lt;li&gt;
Concorrência fácil com o módulo Task

&lt;ul&gt;
&lt;li&gt;O que é um processo de Elixir?&lt;/li&gt;
&lt;li&gt;Criando o projeto&lt;/li&gt;
&lt;li&gt;Iniciando tasks e recuperando resultados&lt;/li&gt;
&lt;li&gt;Código síncrono e assíncrono&lt;/li&gt;
&lt;li&gt;Iniciando processos&lt;/li&gt;
&lt;li&gt;Recuperando o resultado de uma tarefa&lt;/li&gt;
&lt;li&gt;Keyword Lists em Elixir&lt;/li&gt;
&lt;li&gt;Gerenciamento de séries de tarefas&lt;/li&gt;
&lt;li&gt;Por que async_stream retorna um Stream?&lt;/li&gt;
&lt;li&gt;Ligação de processos&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Conhecendo o Supervisor

&lt;ul&gt;
&lt;li&gt;Adicionando um Supervisor&lt;/li&gt;
&lt;li&gt;Usando Task.Supervisor&lt;/li&gt;
&lt;li&gt;Entendendo o Let it Crash&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

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

&lt;/ul&gt;

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

&lt;p&gt;Desde o início da indústria da computação, os fabricantes de hardware e cientistas da computação têm tentado tornar os computadores mais rápidos na execução de programas. No início, a multithreading era a única maneira de alcançar a concorrência, sendo a capacidade de executar duas ou mais tarefas de programação e alternar entre elas para coletar os resultados. Foi assim que os computadores pareciam estar fazendo muitas coisas ao mesmo tempo, quando, na verdade, eram simplesmente multitarefas.&lt;/p&gt;

&lt;p&gt;As CPUs multi-core mudaram isso. Trouxeram paralelismo e permitiram que as tarefas funcionassem lado a lado, independentemente, o que aumentou significativamente o desempenho dos sistemas. Seguiram-se arquiteturas de multiprocessadores, permitindo ainda maior concorrência e paralelismo ao suportar duas ou mais CPUs em uma única máquina. A figura abaixo mostra uma comparação simples entre a concorrência em uma CPU de núcleo único e em uma CPU de núcleo duplo que permite o paralelismo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpo2mawgq9k6iuno7gm7b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpo2mawgq9k6iuno7gm7b.png" alt="Image description" width="800" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Naturalmente, as ferragens de última geração vêm sempre com uma etiqueta de preço elevado. Mas com o advento da computação em nuvem, as coisas mudaram mais uma vez. Hoje em dia, é possível executar código em serviços na nuvem usando máquinas virtuais com dezenas de núcleos de CPU, sem a necessidade de comprar e manter qualquer hardware físico.&lt;/p&gt;

&lt;p&gt;Estes avanços são importantes para nós como engenheiros de software. Queremos escrever um software que tenha bom desempenho e funcione rapidamente. Afinal de contas, ninguém gosta de carregar telas e esperar que o computador termine. Entretanto, a execução do código em um sistema de processador multi-core não o torna automaticamente eficiente. De modo a aproveitar ao máximo os recursos computacionais disponíveis, precisamos escrever software tendo em mente a concorrência e o paralelismo. Felizmente, as modernas linguagens de programação tentam nos ajudar o máximo possível, e a linguagem Elixir não é exceção. De fato, graças ao Erlang, a Máquina Virtual Erlang (BEAM) e a Plataforma de Telecomunicações Abertas (OTP - Open Telecom Platform), o Elixir é uma excelente escolha para a construção de aplicações e processamento de dados concorrentes.&lt;/p&gt;

&lt;p&gt;Vamos abordar as ferramentas mais populares para a realização de trabalhos concorrentes usando Elixir. Vamos verificar os prós e contras de cada uma e ver como funcionam na prática. Algumas delas, como o módulo Task e o GenServer, já vêm com Elixir. Os outros - GenStage, Flow e Broadway - estão disponíveis como bibliotecas autônomas no registro de pacotes Hex.pm. Saber como utilizar cada uma destas ferramentas ajudará você a alavancar a concorrência da maneira mais eficaz e resolver até mesmo os problemas mais desafiadores. Ao longo do caminho, você também aprenderá como construir aplicações tolerantes a falhas, recuperar-se de falhas, usar a contrapressão para lidar com recursos limitados do sistema e muitas outras técnicas úteis.&lt;/p&gt;

&lt;p&gt;Primeiro, vamos analisar o módulo &lt;code&gt;Task&lt;/code&gt;, que faz parte da biblioteca padrão da linguagem Elixir. Ele possui um poderoso conjunto de características que o ajudarão a executar o código concorrentemente. Você também vai ver como lidar com erros e evitar que a aplicação trave quando uma tarefa concorrente trava.&lt;/p&gt;




&lt;h1&gt;
  
  
  Concorrência fácil com o módulo Task &lt;a&gt;
&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;Para executar o código concorrentemente em Elixir, você tem que iniciar um processo e executar seu código dentro desse processo. Você também pode precisar recuperar o resultado e usá-lo para algo mais. Elixir fornece uma função de baixo nível e uma macro para fazer isso - &lt;code&gt;spawn/1&lt;/code&gt; e &lt;code&gt;receive&lt;/code&gt;. Entretanto, usá-los pode ser complicado na prática e você provavelmente acabará com um monte de código repetitivo.&lt;/p&gt;

&lt;p&gt;Elixir também vem com um módulo chamado &lt;code&gt;Task&lt;/code&gt;, que simplifica significativamente o início de processos concorrentes. Ele fornece uma abstração para executar o código concorrentemente, recuperando resultados, manipulando erros e iniciando uma série de processos. Ele possui muitas características com uma API concisa, de modo que raramente (ou nunca) há a necessidade de usar &lt;code&gt;spawn/1&lt;/code&gt; e &lt;code&gt;receive&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Vamos conhecer tudo o que o módulo &lt;code&gt;Task&lt;/code&gt; tem a oferecer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Como iniciar tarefas;&lt;/li&gt;
&lt;li&gt;Diferentes maneiras de recuperar resultados;&lt;/li&gt;
&lt;li&gt;Como lidar com processamento de grandes listas de dados; &lt;/li&gt;
&lt;li&gt;Como lidar com falhas;&lt;/li&gt;
&lt;li&gt;Como funciona a ligação de processos em Elixir;&lt;/li&gt;
&lt;li&gt;Como usar um dos módulos &lt;code&gt;Supervisor&lt;/code&gt; integrados para isolar falhas de processo;&lt;/li&gt;
&lt;li&gt;Discussão sobre a abordagem de Elixir para o tratamento de erros.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Antes de mergulharmos, vamos criar um projeto Elixir para trabalhar primeiro e nos familiarizarmos com algumas das ferramentas de desenvolvimento que vamos usar ao longo deste post.&lt;/p&gt;

&lt;h3&gt;
  
  
  O que é um processo de Elixir? &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Os processos na Elixir são processos Erlang, uma vez que a Elixir funciona na Máquina Virtual Erlang. Ao contrário dos processos do sistema operacional, eles são muito leves em termos de uso de memória e rápidos de iniciar. A VM de Erlang sabe como executá-los concorrentemente e em paralelo (quando uma CPU multi-core está presente). Como resultado, ao utilizar processos, você obtém concorrência e paralelismo de graça.&lt;/p&gt;

&lt;h3&gt;
  
  
  Criando o projeto &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Vamos criar uma aplicação chamada &lt;code&gt;sender&lt;/code&gt; e fingir que estamos enviando e-mails para endereços de e-mail reais. Vamos usar o módulo &lt;code&gt;Task&lt;/code&gt; mais tarde para desenvolver algumas de suas funcionalidades. &lt;/p&gt;

&lt;p&gt;Primeiramente, vamos usar a ferramenta de linha de comando mista para a montagem de nosso novo projeto:&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="nv"&gt;$ &lt;/span&gt;mix new sender &lt;span class="nt"&gt;--sup&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isto cria um diretório para o nosso projeto &lt;code&gt;sender&lt;/code&gt; com um monte de arquivos e pastas dentro. Note que também utilizamos o argumento &lt;code&gt;--sup&lt;/code&gt;, que criará uma aplicação com uma árvore de supervisão. Veremos sobre árvores de supervisão mais adiante.&lt;/p&gt;

&lt;p&gt;Para manter nosso projeto e nossos exemplos simples, não vamos enviar e-mails de verdade. Entretanto, ainda precisamos de alguma lógica comercial para nossas experiências. Podemos usar a função Process.sleep/1 para fingir que estamos enviando um e-mail, que normalmente é uma operação lenta e pode levar alguns segundos para ser concluída. Quando chamado com um número inteiro, o Process.sleep/1 interrompe o processo atual durante um determinado período em milissegundos. Isto é muito útil, porque você pode usá-lo para simular um código que leva muito tempo para ser completo. Você também pode usá-lo para testar vários casos extremos, como veremos mais tarde. Naturalmente, em aplicações de produção real, você substituirá isto por sua lógica comercial real. Mas por enquanto, vamos fingir que estamos fazendo um trabalho muito intensivo.&lt;/p&gt;

&lt;p&gt;Abra seu arquivo &lt;code&gt;sender/lib/sender.ex&lt;/code&gt; e adicione o seguinte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;send_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="no"&gt;Process&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Email to &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; sent"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"email_sent"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ao chamar esta função, a execução será suspensa por três segundos e uma mensagem será impressa, o que será útil para a depuração. Também retorna uma tupla &lt;code&gt;{:ok, "email_sent"}&lt;/code&gt; para indicar que o email foi enviado com sucesso.&lt;/p&gt;

&lt;p&gt;Agora que tudo está pronto, podemos começar. Sugiro que você mantenha uma sessão de terminal com o IEx aberta e seu editor de texto favorito ao lado, para você poder fazer e executar mudanças à medida que avançamos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Iniciando Tasks e Recuperando Resultados &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Antes de saltar para o módulo &lt;code&gt;Task&lt;/code&gt;, vamos ver como as coisas estão funcionando. Vamos chamar a função &lt;code&gt;send_email/1&lt;/code&gt; do IEx, e passar um endereço de email fictício como um argumento.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Sender&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"hello@world.com"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;Email&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="nv"&gt;@world&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt; &lt;span class="n"&gt;sent&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"email_sent"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você notou o atraso/delay? Tivemos que esperar três segundos até vermos a produção e o resultado impresso. Na verdade, mesmo o &lt;code&gt;iex&amp;gt; prompt&lt;/code&gt; não estava aparecendo. Vamos adicionar outra função, &lt;code&gt;notify_all/1&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;Em &lt;code&gt;sender/lib/sender.ex&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;notify_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;emails&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;emails&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;send_email&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="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A função &lt;code&gt;notify_all/1&lt;/code&gt; usa &lt;code&gt;Enum.each/2&lt;/code&gt; para iterar sobre os emails variados, que é uma lista de strings. Para cada item da lista, vamos chamar a função &lt;code&gt;send_email/1&lt;/code&gt;. Vamos testar esta função no IEx, mas primeiro precisamos de alguns dados de teste. Crie um arquivo &lt;code&gt;.iex.exs&lt;/code&gt; na pasta principal do projeto &lt;code&gt;sender&lt;/code&gt; no mesmo local onde está o &lt;code&gt;mix.exs&lt;/code&gt;. Adicione o seguinte:&lt;/p&gt;

&lt;p&gt;Em &lt;code&gt;sender/.iex.exs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;emails&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="s2"&gt;"hello@world.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"hola@world.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"nihao@world.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"konnichiwa@world.com"&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;Salve o arquivo, saia do IEx e inicie-o novamente com &lt;code&gt;iex -S mix&lt;/code&gt;. Digite &lt;code&gt;emails&lt;/code&gt; e pressione enter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&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="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;emails&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"hello@world.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"hola@world.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"nihao@world.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="s2"&gt;"konnichiwa@world.com"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isto lhe poupará muita digitação. Todo o código Elixir em &lt;code&gt;.iex.exs&lt;/code&gt; será executado quando o IEx iniciar, portanto, isto persistirá entre as sessões do IEx. Agora vamos usar os dados de teste com &lt;code&gt;notify_all/1&lt;/code&gt;. Você pode adivinhar quanto tempo levará para enviar todos os emails? Vamos descobrir:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Sender&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;notify_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;emails&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;Email&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="nv"&gt;@world&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt; &lt;span class="n"&gt;sent&lt;/span&gt;
&lt;span class="no"&gt;Email&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;hola&lt;/span&gt;&lt;span class="nv"&gt;@world&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt; &lt;span class="n"&gt;sent&lt;/span&gt;
&lt;span class="no"&gt;Email&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;nihao&lt;/span&gt;&lt;span class="nv"&gt;@world&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt; &lt;span class="n"&gt;sent&lt;/span&gt;
&lt;span class="no"&gt;Email&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;konnichiwa&lt;/span&gt;&lt;span class="nv"&gt;@world&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt; &lt;span class="n"&gt;sent&lt;/span&gt;
&lt;span class="ss"&gt;:ok&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Foram necessárias quatro chamadas para &lt;code&gt;send_email/1&lt;/code&gt; e cerca de doze segundos para completar. Só de esperar a saída no IEx parecia uma eternidade. Isto não é nada bom!!! À medida que a nossa base de usuários cresce, levará uma eternidade para enviar nossos emails.&lt;/p&gt;

&lt;p&gt;Não se desespere - podemos acelerar significativamente nosso código usando o módulo Task. No entanto, antes de saltarmos para dentro dele, vamos tirar um momento para falar sobre dois conceitos importantes na programação: código &lt;strong&gt;síncrono&lt;/strong&gt; e &lt;strong&gt;assíncrono&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Código síncrono e assíncrono &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Tanto o código &lt;strong&gt;síncrono&lt;/strong&gt; como &lt;strong&gt;assíncrono&lt;/strong&gt; são executados aos mesmo tempo, a diferença é que o &lt;strong&gt;código assíncrono não há uma ordem específica&lt;/strong&gt; e por isso é considerado &lt;strong&gt;concorrente&lt;/strong&gt;, diferentemente do síncrono que há uma sequencia específica.&lt;/p&gt;

&lt;p&gt;Por padrão, quando você executa algum código em Elixir, você tem que esperar que ele seja concluído. Você não pode fazer nada enquanto isso, e você obtém o resultado assim que o código tiver terminado. O código é executado de forma &lt;strong&gt;síncrona&lt;/strong&gt; e é algumas vezes chamado de &lt;strong&gt;código bloqueador (blocking code)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;O oposto disto é executar o código de forma &lt;strong&gt;assíncrona&lt;/strong&gt;. Neste caso, você pede ao tempo de execução da programação para executar o código, mas continua com o resto do programa. O código &lt;strong&gt;assíncrono&lt;/strong&gt; roda em segundo plano porque a aplicação continua rodando, como se nada tivesse acontecido. Eventualmente, quando o código &lt;strong&gt;assíncrono&lt;/strong&gt; termina, você pode recuperar o resultado. Como o código &lt;strong&gt;assíncrono&lt;/strong&gt; não bloqueia a execução principal do programa, ele é chamado de &lt;strong&gt;código não-bloqueador (non-blocking code)&lt;/strong&gt;. O &lt;strong&gt;código assíncrono também é concorrente&lt;/strong&gt;, já que nos permite continuar fazendo outros trabalhos. A figura abaixo ilustra a diferença entre código &lt;strong&gt;síncrono&lt;/strong&gt; e &lt;strong&gt;assíncrono&lt;/strong&gt; em um programa de panificação:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv8q4kzgabodour0kxb07.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv8q4kzgabodour0kxb07.png" alt="Image description" width="800" height="361"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Mix flour = Misture a farinha&lt;/li&gt;
&lt;li&gt;Rest the dough = Descanse a massa&lt;/li&gt;
&lt;li&gt;Pre-heat oven = Pré-aqueça o forno&lt;/li&gt;
&lt;li&gt;Bake = Assar&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Uma vez que apenas a etapa final de cozimento (Bake) requer que o forno seja pré-aquecido (Pre-heat), você pode fazer o pré-aquecimento do forno de forma assíncrona e fazer algo mais enquanto isso. Em comparação com a versão síncrona, isto diminui significativamente o tempo necessário para completar o conjunto de instruções.&lt;/p&gt;

&lt;p&gt;Você já deve ter adivinhado que a função &lt;code&gt;notify_all/1&lt;/code&gt; está enviando cada email de forma síncrona. É por isso que está demorando tanto para ser concluída. Para melhorar isto, vamos converter nosso código para ser executado de forma assíncrona. Graças ao módulo &lt;code&gt;Task&lt;/code&gt; do Elixir, precisaremos apenas de algumas pequenas mudanças para conseguir isso. Vamos ver como funciona.&lt;/p&gt;

&lt;h3&gt;
  
  
  Iniciando processos &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;O módulo &lt;code&gt;Task&lt;/code&gt; contém uma série de funções muito úteis para executar código de forma assíncrona e concorrente. Uma delas é &lt;code&gt;start/1&lt;/code&gt;. Ele aceita uma função como um argumento, e dentro dessa função devemos fazer todo o trabalho que pretendemos fazer. Vamos experimentar isso rapidamente no IEx:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Hello async world!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;Hello&lt;/span&gt; &lt;span class="n"&gt;async&lt;/span&gt; &lt;span class="n"&gt;world!&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;#PID&amp;lt;0.266.0&amp;gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você viu a mensagem impressa instantaneamente porque é uma operação rápida, mas o resultado real foi &lt;code&gt;{:ok, #PID&amp;lt;0.266.0&amp;gt;}&lt;/code&gt;. Retornar uma tupla como &lt;code&gt;{:ok, result}&lt;/code&gt; ou &lt;code&gt;{:erro, message}&lt;/code&gt; é uma prática comum no Elixir. O resultado foi &lt;code&gt;:ok&lt;/code&gt; para o sucesso e &lt;code&gt;#PID&amp;lt;0.266.0&amp;gt;&lt;/code&gt;. PID significa identificador de processo (process identifier) - um número que identifica de forma única um processo Elixir.&lt;/p&gt;

&lt;p&gt;Já temos o &lt;code&gt;send_email/1&lt;/code&gt; pronto, por isso podemos usar o &lt;code&gt;Task.start/1&lt;/code&gt; para chamá-lo. Vamos fazer algumas mudanças:&lt;/p&gt;

&lt;p&gt;Em &lt;code&gt;sender/lib/sender.change1.ex&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;notify_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;emails&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;emails&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="n"&gt;send_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em seguida, recompilar e executar &lt;code&gt;notify_all/1&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Sender&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;notify_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;emails&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="ss"&gt;:ok&lt;/span&gt;
&lt;span class="no"&gt;Email&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="nv"&gt;@world&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt; &lt;span class="n"&gt;sent&lt;/span&gt;
&lt;span class="no"&gt;Email&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;hola&lt;/span&gt;&lt;span class="nv"&gt;@world&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt; &lt;span class="n"&gt;sent&lt;/span&gt;
&lt;span class="no"&gt;Email&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;nihao&lt;/span&gt;&lt;span class="nv"&gt;@world&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt; &lt;span class="n"&gt;sent&lt;/span&gt;
&lt;span class="no"&gt;Email&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;konnichiwa&lt;/span&gt;&lt;span class="nv"&gt;@world&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt; &lt;span class="n"&gt;sent&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isto deve ser significativamente mais rápido - de fato, quatro vezes mais rápido! Todas as funções foram chamadas concorrentemente e terminadas ao mesmo tempo, imprimindo a mensagem de sucesso como esperávamos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Recuperando o resultado de uma tarefa &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Task.start/1&lt;/code&gt; tem uma limitação por projeto: não retorna o resultado da função que foi executada. Isto pode ser útil em alguns casos, mas na maioria das vezes você precisa do resultado para alguma outra coisa. Seria ótimo se modificássemos nosso código e retornássemos um resultado significativo quando todos os emails forem enviados com sucesso.&lt;/p&gt;

&lt;p&gt;Para recuperar o resultado de uma função, você tem que usar o &lt;code&gt;Task.async/1&lt;/code&gt;. Ela retorna uma estrutura &lt;code&gt;%Task{}&lt;/code&gt; que você pode atribuir a uma variável para uso posterior. Você pode experimentá-la no IEx assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;async&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Sender&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"hello@world.com"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="ss"&gt;owner:&lt;/span&gt; &lt;span class="c1"&gt;#PID&amp;lt;0.145.0&amp;gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;pid:&lt;/span&gt; &lt;span class="c1"&gt;#PID&amp;lt;0.165.0&amp;gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;ref:&lt;/span&gt; &lt;span class="c1"&gt;#Reference&amp;lt;0.713486762.1657274369.63141&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 &lt;code&gt;send_email/1&lt;/code&gt; está agora rodando em segundo plano. Enquanto isso, estamos livres para fazer outros trabalhos, conforme necessário. &lt;strong&gt;Você pode adicionar mais lógica comercial ou até mesmo iniciar outras tarefas&lt;/strong&gt;. Quando você precisar do resultado real da tarefa, você pode recuperá-la usando a variável &lt;code&gt;task&lt;/code&gt;. Vamos dar uma olhada mais de perto no que esta variável contém:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;owner&lt;/code&gt; (proprietário) é o PID do processo que iniciou o processo Task.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pid&lt;/code&gt; é o identificador do próprio processo Task.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ref&lt;/code&gt; é a referência do monitor de processo (process monitor reference).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Não vamos nos aprofundar no monitoramento de processos (Process monitoring) aqui. Entretanto, vale a pena saber que você pode monitorar um processo e receber notificações dele usando um valor de referência - por exemplo, quando e como um processo sai.&lt;/p&gt;

&lt;p&gt;Para recuperar o resultado da tarefa, você pode usar tanto o &lt;code&gt;Task.await/1&lt;/code&gt; ou o &lt;code&gt;Task.yield/1&lt;/code&gt; que aceita uma estrutura Task como um argumento. Há uma diferença importante na forma de trabalho do &lt;code&gt;await/1&lt;/code&gt; e do &lt;code&gt;yield/1&lt;/code&gt;, portanto, você tem que escolher sabiamente. &lt;strong&gt;Ambos param o programa e tentam recuperar o resultado da tarefa&lt;/strong&gt;. A diferença vem da maneira como eles lidam com os &lt;em&gt;tempos de espera do processo (process timeouts)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Os tempos de espera do processo garantem que os processos não fiquem presos para sempre. Para mostrar como eles funcionam, vamos aumentar o tempo que a função &lt;code&gt;send_email/1&lt;/code&gt; leva para 30 segundos, apenas temporariamente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;send_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="no"&gt;Process&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30_000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Email to &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; sent"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"email_sent"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em seguida, &lt;code&gt;recompile/0&lt;/code&gt; no IEx . Agora vamos executar o código de forma assíncrona e canalizar o resultado da task em &lt;code&gt;await/1&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;async&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Sender&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"hi@world.com"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;await&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Após cinco segundos, você receberá uma exceção semelhante a esta:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;exited&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;await&lt;/span&gt;&lt;span class="p"&gt;(%&lt;/span&gt;&lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;owner:&lt;/span&gt; &lt;span class="c1"&gt;#PID&amp;lt;0.144.0&amp;gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;pid:&lt;/span&gt; &lt;span class="c1"&gt;#PID&amp;lt;0.151.0&amp;gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;ref:&lt;/span&gt; &lt;span class="c1"&gt;#Reference&amp;lt;0.2297312895.3696492546.156249&amp;gt;}, 5000)&lt;/span&gt;
    &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;EXIT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="n"&gt;out&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;elixir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="ss"&gt;ex:&lt;/span&gt;&lt;span class="mi"&gt;607&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;await&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ao utilizar o &lt;code&gt;await/1&lt;/code&gt;, esperamos que uma tarefa termine dentro de um certo período de tempo. Por padrão, este tempo é definido para 5000ms, que é de cinco segundos. Você pode mudar isso passando um inteiro com a quantidade de milissegundos como segundo argumento, por exemplo &lt;code&gt;Task.await(task, 10_000)&lt;/code&gt;. Você também pode desativar o tempo limite passando o átomo &lt;code&gt;:infinity&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Em comparação, o &lt;code&gt;Task.yield/1&lt;/code&gt; simplesmente retorna nulo se a tarefa não tiver sido concluída. O timeout de &lt;code&gt;yield/1&lt;/code&gt; também é de 5000ms, mas não causa uma exceção e um travamento (crash). Você também pode fazer &lt;code&gt;Task.yield(task)&lt;/code&gt; repetidamente para verificar um resultado, o que não é permitido por &lt;code&gt;await/1&lt;/code&gt;. Uma tarefa concluída retornará &lt;code&gt;{:ok, resultado}&lt;/code&gt; ou &lt;code&gt;{:exit, reason}&lt;/code&gt;. Você pode ver isto em ação:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;async&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Sender&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"hi@world.com"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="ss"&gt;owner:&lt;/span&gt; &lt;span class="c1"&gt;#PID&amp;lt;0.135.0&amp;gt;,&lt;/span&gt;
&lt;span class="ss"&gt;pid:&lt;/span&gt; &lt;span class="c1"&gt;#PID&amp;lt;0.147.0&amp;gt;,&lt;/span&gt;
&lt;span class="ss"&gt;ref:&lt;/span&gt; &lt;span class="c1"&gt;#Reference&amp;lt;0.3033103973.1551368196.24818&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;yield&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;yield&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="no"&gt;Email&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;hi&lt;/span&gt;&lt;span class="nv"&gt;@world&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt; &lt;span class="n"&gt;sent&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;yield&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"email_sent"&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;yield&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;nil&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esta saída ilustra o que acontece quando você chama &lt;code&gt;Task.yield/1&lt;/code&gt; enquanto a tarefa ainda está em execução - você recebe &lt;code&gt;nil (nulo)&lt;/code&gt;. Assim que a mensagem de sucesso é impressa, recebemos &lt;code&gt;{:ok, {:ok, "e-mail_sent"}}&lt;/code&gt; como esperado. Você também pode usar &lt;code&gt;yield/2&lt;/code&gt; e fornecer seu próprio timeout (tempo de espera), de modo semelhante a &lt;code&gt;await/2&lt;/code&gt;, mas a opção &lt;code&gt;:infinity&lt;/code&gt; não é permitida. Note que você só receberá o resultado de &lt;code&gt;yield/1&lt;/code&gt; uma vez, e as chamadas subsequentes retornarão &lt;code&gt;nil&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Você pode estar se perguntando o que acontece se nossa tarefa está emperrada e nunca termina? Enquanto &lt;code&gt;await/1&lt;/code&gt; se encarrega de parar a tarefa, o &lt;code&gt;yield/1&lt;/code&gt; a deixará em funcionamento. É uma boa idéia parar a tarefa manualmente, chamando o &lt;code&gt;Task.shutdown(task)&lt;/code&gt;. A função &lt;code&gt;shutdown/1&lt;/code&gt; também aceita um timeout e dá ao processo uma última chance de ser concluído, antes de pará-lo. Se ele for concluído, você receberá o resultado normalmente. Você também pode parar um processo imediatamente (e de forma bastante violenta) usando o átomo &lt;code&gt;:brutal_kill&lt;/code&gt; como segundo argumento.&lt;/p&gt;

&lt;p&gt;Como você pode ver, usar &lt;code&gt;yield/1&lt;/code&gt; e &lt;code&gt;shutdown/1&lt;/code&gt; é um pouco mais trabalhoso do que &lt;code&gt;await/1&lt;/code&gt;. Qual deles usar depende de seu caso de uso. Muitas vezes, o timeout (tempo de espera) da tarefa justifica uma exceção, caso em que o &lt;code&gt;await/1&lt;/code&gt; será mais conveniente de usar. Sempre que você precisar de mais controle sobre o timeout e o encerramento, você pode mudar para &lt;code&gt;yield/1&lt;/code&gt; e &lt;code&gt;shutdown/1&lt;/code&gt;. A parte importante é que, após utilizar &lt;code&gt;async/1&lt;/code&gt;, você deve sempre processar o resultado, usando ou &lt;code&gt;await/1&lt;/code&gt;, ou &lt;code&gt;yield/1&lt;/code&gt; seguido de &lt;code&gt;shutdown/1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Para a nossa lógica &lt;code&gt;notify_all/1&lt;/code&gt;, vamos usar o &lt;code&gt;await/1&lt;/code&gt; para simplificar. Lembre-se de reverter nossa mudança anterior no &lt;code&gt;send_email/1&lt;/code&gt; e definir &lt;code&gt;Process.sleep/1&lt;/code&gt; de volta para 3000ms:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;send_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="no"&gt;Process&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora vamos trocar &lt;code&gt;Task.start/1&lt;/code&gt; para &lt;code&gt;Task.async/1&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;Em &lt;code&gt;sender/lib/sender.change2.ex&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;notify_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;emails&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;emails&lt;/span&gt;
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;async&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;send_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;await&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="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Observe que também estamos usando Enum.map/2 em vez de Enum.each/2, porque queremos mapear cada seqüência de e-mails para sua estrutura de tarefas correspondente. A estrutura é necessária para recuperar o resultado de cada processo. &lt;/p&gt;

&lt;p&gt;Usamos aqui a sintaxe da função shorthand (abreviação) do Elixir - &amp;amp;Task.await/1. Se você não está familiarizado com ela, é simplesmente equivalente à escrita:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
  &lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;await&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vamos experimentar as últimas mudanças no IEx:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Sender&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;notify_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;emails&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;Email&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="nv"&gt;@world&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt; &lt;span class="n"&gt;sent&lt;/span&gt;
&lt;span class="no"&gt;Email&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;hola&lt;/span&gt;&lt;span class="nv"&gt;@world&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt; &lt;span class="n"&gt;sent&lt;/span&gt;
&lt;span class="no"&gt;Email&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;nihao&lt;/span&gt;&lt;span class="nv"&gt;@world&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt; &lt;span class="n"&gt;sent&lt;/span&gt;
&lt;span class="no"&gt;Email&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;konnichiwa&lt;/span&gt;&lt;span class="nv"&gt;@world&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt; &lt;span class="n"&gt;sent&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;ok:&lt;/span&gt; &lt;span class="s2"&gt;"email_sent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;ok:&lt;/span&gt; &lt;span class="s2"&gt;"email_sent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;ok:&lt;/span&gt; &lt;span class="s2"&gt;"email_sent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;ok:&lt;/span&gt; &lt;span class="s2"&gt;"email_sent"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A função retornou uma lista de resultados. Para cada tarefa, você tem uma tupla &lt;code&gt;ok: "email_sent"&lt;/code&gt;, que é o que a função &lt;code&gt;send_email/1&lt;/code&gt; retorna. Em sua lógica comercial, você pode retornar um &lt;code&gt;{:erro, "mensagem de erro"}&lt;/code&gt; quando algo der errado. Então você será capaz de coletar o erro e potencialmente tentar novamente a operação ou fazer algo mais com o resultado.&lt;/p&gt;

&lt;p&gt;A criação de tarefas a partir de listas de itens é na verdade muito comum em Elixir. Em seguida, vamos usar uma função especificamente projetada para fazer isso. Ela também oferece uma série de recursos adicionais, especialmente úteis quando se trabalha com grandes listas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Keyword Lists em Elixir &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Elixir tem uma notação especial para listas contendo tuplas de chave-valor, também conhecidas como keyword lists (listas de palavras-chave). Cada item da lista de palavras-chave deve ser uma tupla de dois elementos. O primeiro elemento é o nome da chave, que deve ser um átomo. O segundo é o valor e pode ser de qualquer tipo. &lt;/p&gt;

&lt;p&gt;Elas são exibidas no IEx sem as chaves (curly braces), assim &lt;code&gt;[ok: "email_sent"]&lt;/code&gt;. Isto é equivalente a &lt;code&gt;[{:ok, "email_sent"}]&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gerenciamento de séries de tarefas &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Imaginemos que temos um milhão de usuários, e queremos enviar um e-mail a todos eles. Podemos usar &lt;code&gt;Enum.map/2&lt;/code&gt; e &lt;code&gt;Task.async/1&lt;/code&gt; como fizemos antes, mas iniciar um milhão de processos colocará uma pressão repentina sobre os recursos de nosso sistema. Isso pode degradar o desempenho do sistema e potencialmente fazer com que outros serviços não respondam. Nosso provedor de serviços de e-mail também não ficará feliz, pois também colocamos muita pressão sobre a infra-estrutura de e-mail deles.&lt;/p&gt;

&lt;p&gt;Por outro lado, não queremos enviar e-mails um a um, porque é lento e ineficiente. Parece que estamos em uma encruzilhada e, seja qual for o caminho que tomemos, acabamos em perigo. Não queremos escolher entre desempenho e confiabilidade - queremos ser capazes de executar processos do módulo Task para alavancar a concorrência, mas garantir que não sobrecarregamos nossos recursos de sistema à medida que dimensionamos nosso produto e aumentamos nossa base de usuários.&lt;/p&gt;

&lt;p&gt;A solução para nossos problemas é &lt;code&gt;async_stream/3&lt;/code&gt;. É outra função muito útil do módulo Task que é projetado para criar processos de tarefas a partir de uma lista de itens. Para cada item da lista, &lt;code&gt;async_stream/3&lt;/code&gt; iniciará um processo e executará a função que fornecemos para processar o item. Funciona como &lt;code&gt;Enum.map/2&lt;/code&gt; e &lt;code&gt;Task.async/2&lt;/code&gt; combinados, com uma grande diferença: você pode definir um limite no número de processos em execução ao mesmo tempo. A figura abaixo ilustra como isto funciona:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4k04vtzszdy558y5qc06.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4k04vtzszdy558y5qc06.png" alt="Image description" width="800" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Neste exemplo, o limite de concorrência é fixado em quatro, portanto, mesmo que você tenha uma lista de cem itens, no máximo apenas quatro processos serão executados de forma concorrente em um determinado momento. Este é um exemplo de tratamento de contrapressão/retaguarda (back-pressure), que podemos discutir em profundidade em um próximo post, falando sobre pipelines de processamento de dados com GenStage. Por enquanto, tudo o que você precisa saber é que esta estratégia de manuseio de processos é ótima para evitar picos repentinos de uso do sistema. Em outras palavras, você obtém a concorrência e o desempenho sem sacrificar a confiabilidade.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn9mjxfmxk2ypdzdb5zdd.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn9mjxfmxk2ypdzdb5zdd.gif" alt="Image description" width="488" height="130"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como o nome da função sugere, &lt;code&gt;async_stream/3&lt;/code&gt; retorna um &lt;strong&gt;Stream&lt;/strong&gt;. Streams em Elixir são estruturas de dados que realizam uma ou mais operações que não funcionam imediatamente, somente quando explicitamente informado. É por isso que às vezes são chamados de listas preguiçosas. Vamos ver o que acontece quando executamos esta função a partir do IEx:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;async_stream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;emails&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="no"&gt;Sender&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send_email&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="c1"&gt;#Function&amp;lt;1.35903181/2 in Task.build_stream/3&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em vez do resultado habitual, recebemos uma função, que vai criar um Stream. É importante entender como funcionam os fluxos, então vamos dar outro exemplo rápido no IEx:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&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="mi"&gt;2&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="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;&amp;amp;1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;#Stream&amp;lt;[&lt;/span&gt;
  &lt;span class="ss"&gt;enum:&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="mi"&gt;2&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="ss"&gt;funs:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="c1"&gt;#Function&amp;lt;49.33009823/1 in Stream.map/2&amp;gt;]&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se tivéssemos usado &lt;code&gt;Enum.map/2&lt;/code&gt; a função teria retornado [2, 4, 6]. Em vez disso, o fluxo de resultados contém simplesmente a entrada inicial e uma lista de operações &lt;code&gt;funs&lt;/code&gt;. Estas operações podem ser executadas posteriormente. Como tanto o Stream quanto o Enum implementam o protocolo Enumerable, muitas funções Enum têm uma alternativa preguiçosa no módulo Stream.&lt;/p&gt;

&lt;p&gt;Uma maneira de executar um fluxo é usar a função &lt;code&gt;Stream.run/1&lt;/code&gt;. Entretanto, o &lt;code&gt;Stream.run/1&lt;/code&gt; sempre retorna :ok, então só é útil quando você não está interessado no resultado final. Ao invés disso, você pode usar &lt;code&gt;Enum.to_list/1&lt;/code&gt;, que tentará converter o fluxo para uma estrutura de dados List. Como resultado desta conversão, todas as operações no fluxo serão executadas, e o resultado será retornado como uma lista. Outras funções no módulo Enum também forçarão o fluxo a ser executado, como &lt;code&gt;Enum.reduce/3&lt;/code&gt;. Você pode usá-las se pretender trabalhar mais com o resultado.&lt;/p&gt;

&lt;p&gt;Agora, vamos atualizar o &lt;code&gt;notify_all/1&lt;/code&gt; para usar o &lt;code&gt;async_stream/3&lt;/code&gt;. Desta vez, porém, vamos executar o stream usando &lt;code&gt;Enum.to_list/1&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;Em &lt;code&gt;sender/lib/sender.change3.ex&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;notify_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;emails&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;emails&lt;/span&gt;
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;async_stream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;send_email&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="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_list&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E dê uma olhada no IEx, mas não se esqueça de rodar &lt;code&gt;recompile/0&lt;/code&gt; primeiro:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Sender&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;notify_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;emails&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;Email&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="nv"&gt;@world&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt; &lt;span class="n"&gt;sent&lt;/span&gt;
&lt;span class="no"&gt;Email&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;hola&lt;/span&gt;&lt;span class="nv"&gt;@world&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt; &lt;span class="n"&gt;sent&lt;/span&gt;
&lt;span class="no"&gt;Email&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;nihao&lt;/span&gt;&lt;span class="nv"&gt;@world&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt; &lt;span class="n"&gt;sent&lt;/span&gt;
&lt;span class="no"&gt;Email&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;konnichiwa&lt;/span&gt;&lt;span class="nv"&gt;@world&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt; &lt;span class="n"&gt;sent&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="ss"&gt;ok:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"email_sent"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="ss"&gt;ok:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"email_sent"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="ss"&gt;ok:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"email_sent"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="ss"&gt;ok:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"email_sent"&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;
  
  
  Por que async_stream retorna um Stream? &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Os Streams são projetados para emitir uma série de valores, um por um. Assim que o &lt;code&gt;Task.async_stream/3&lt;/code&gt; descobre que um processo de tarefa terminou, ele emitirá o resultado e tomará o próximo elemento da entrada, iniciando um novo processo. Isto significa que ele pode manter uma série de eventos concorrentes, o que é um dos benefícios do &lt;code&gt;async_stream/3&lt;/code&gt;. Você também pode usar todas as outras funções do módulo Stream para compor fluxos complexos de processamento de dados.&lt;/p&gt;

&lt;p&gt;Como você pode ver, a saída é semelhante à do exemplo &lt;code&gt;Task.async/2&lt;/code&gt;. Entretanto, dependendo de quantos núcleos lógicos (threads) sua máquina tem, o tempo que leva para que a função seja concluída pode ser diferente.&lt;/p&gt;

&lt;p&gt;Como mencionamos anteriormente, &lt;code&gt;async_stream/3&lt;/code&gt; mantém um limite em quantos processos podem ser executados ao mesmo tempo. Por padrão, este limite é definido para o número de núcleos lógicos disponíveis no sistema. Anteriormente utilizávamos o &lt;code&gt;Task.async/2&lt;/code&gt; para iniciar manualmente um processo para cada um dos quatro itens. Isto significa que se você tiver uma CPU com menos de quatro núcleos lógicos, o &lt;code&gt;async_stream/3&lt;/code&gt; parecerá mais lento. Você pode alterar facilmente este comportamento padrão através do parâmetro opcional &lt;code&gt;max_concurrency&lt;/code&gt;. Vamos definir o &lt;code&gt;max_concurrency&lt;/code&gt; para 1 temporariamente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;async_stream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;send_email&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="ss"&gt;max_concurrency:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quando você tentar as novas mudanças novamente, você verá que os e-mails são enviados um a um. Isto não é muito útil na prática, mas demonstra como funciona o &lt;code&gt;max_concurrency&lt;/code&gt;. Você pode reverter a mudança ou defini-la para um número ainda maior. Em aplicações de produção, você pode comparar (benchmark) se o &lt;code&gt;max_concurrency&lt;/code&gt; funciona melhor para seu caso de uso, levando em consideração os recursos de seu sistema e a necessidade de desempenho.&lt;/p&gt;

&lt;p&gt;Outra opção que precisa ser mencionada é &lt;code&gt;:ordered&lt;/code&gt;. Atualmente, &lt;code&gt;async_stream/3&lt;/code&gt; assume que queremos os resultados na mesma ordem em que foram originalmente ordenados. Esta preservação da ordem pode potencialmente retardar nosso processamento, pois &lt;code&gt;async_stream/3&lt;/code&gt; esperará que um processo lento seja concluído antes de passar para o próximo.&lt;/p&gt;

&lt;p&gt;Em nosso caso, só precisamos dos resultados para verificar se um e-mail foi enviado com sucesso ou não. Não necessariamente precisamos deles exatamente na mesma ordem. Podemos potencialmente agilizar as coisas desativando a ordenação assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;async_stream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;send_email&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="ss"&gt;ordered:&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora o &lt;code&gt;async_stream/3&lt;/code&gt; não ficará parado se um processo estiver demorando mais do que outros.&lt;/p&gt;

&lt;p&gt;Processos iniciados por &lt;code&gt;async_stream/3&lt;/code&gt; também estão sujeitos a timeouts (tempo de resposta), assim como aqueles iniciados por &lt;code&gt;start/1&lt;/code&gt; e &lt;code&gt;async/2&lt;/code&gt;. O parâmetro opcional &lt;code&gt;:timeout&lt;/code&gt; é suportado e o valor padrão é de 5000ms. Quando uma tarefa atinge o timeout, ela produzirá uma exceção, interrompendo o stream/fluxo e interrompendo o processo atual. Este comportamento pode ser alterado usando um argumento opcional &lt;code&gt;:on_timeout&lt;/code&gt;, que você pode definir para &lt;code&gt;:kill_task&lt;/code&gt;. Este argumento é similar ao &lt;code&gt;:brutal_kill&lt;/code&gt; suportado pelo &lt;code&gt;Task.shutdown/2&lt;/code&gt;. Segue um exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;async_stream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;send_email&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="ss"&gt;on_timeout:&lt;/span&gt; &lt;span class="ss"&gt;:kill_task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como resultado do uso da opção &lt;code&gt;:kill_task&lt;/code&gt;, quando um processo termina com um timeout, o &lt;code&gt;async_stream/3&lt;/code&gt; irá ignorá-lo e continuará normalmente.&lt;/p&gt;

&lt;p&gt;Um processo pode falhar por muitas razões. Falamos de exceções de timeout, que acontecem quando os processos levam muito tempo para serem concluídos. Isto pode ser porque o trabalho que ele está fazendo consome muito tempo ou porque ele está esperando por uma API de terceiros lenta para responder. Às vezes é um erro inesperado que causa uma exceção. O importante é que quando um processo trava, ele também pode travar o processo que o iniciou, o que por sua vez trava seu processo pai, desencadeando uma reação em cadeia que pode, em última instância, travar toda a sua aplicação.&lt;/p&gt;

&lt;p&gt;Isto parece um desastre de programação esperando para acontecer, mas a boa notícia é que em Elixir, graças a Erlang, tem um conjunto de ferramentas poderosas para gerenciar processos, pegar acidentes e se recuperar rapidamente. Na próxima seção, vamos explicar por que esta reação em cadeia é uma coisa boa, como isolá-la e como utilizá-la a nosso favor. Você também começará a aprender como construir as aplicações tolerantes a falhas pelas quais a linguagem Elixir é famosa.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ligação de processos &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Os processos em Elixir podem ser ligados entre si, e os processos do Task são normalmente ligados automaticamente ao processo que os iniciou. Este vínculo é simplesmente chamado de ligação de processos (process link). As ligações de processos têm um papel importante na construção de aplicações concorrentes e tolerantes a falhas. Elas nos ajudam a desligar imediatamente partes do sistema, ou mesmo todo o sistema quando necessário, impedindo que a aplicação funcione em um péssimo estado. Vamos ver por que as ligações de processos são úteis e como funcionam, observando alguns exemplos. A figura a seguir mostra três processos ligados entre si:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F68ttmbnkvuly2xsuke5d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F68ttmbnkvuly2xsuke5d.png" alt="Image description" width="800" height="293"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como você pode ver, o Processo C acabou de falhar. Imagine que o Processo B continua funcionando, sem saber do acidente. Ele espera receber um resultado do Processo C e se reportar ao Processo A. Entretanto, isto nunca acontecerá, portanto este sistema é mantido em um péssimo estado.&lt;/p&gt;

&lt;p&gt;Isto pode ser evitado graças à ligação de processos. Quando dois processos estão ligados, eles formam uma relação especial - assim que um sai, o outro será notificado. Quando se tem uma cadeia de processos interligados, todos eles serão eventualmente notificados quando ocorrer um acidente. Por padrão, os processos interligados terminarão e limparão a memória que eles utilizavam, evitando outros problemas potenciais no decorrer da linha. Isto significa que o acidente do Processo C desencadeará uma reação em cadeia e o Processo B terminará, seguido pelo Processo A.&lt;/p&gt;

&lt;p&gt;Entretanto, uma reação em cadeia como esta só faz sentido quando ocorre um erro grave. Dê uma olhada nesta figura, que mostra os processos em execução para uma aplicação web bancária:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fndhvxdt9u7xkktc3yiv7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fndhvxdt9u7xkktc3yiv7.png" alt="Image description" width="800" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A maioria das aplicações web dependem muito de um banco de dados, e o acesso ao banco de dados é geralmente gerenciado por um processo. Neste exemplo, o processo de Repo tem esta responsabilidade. Se o Repo falhar, porque o banco de dados se torna indisponível, esta aplicação não poderá funcionar de forma alguma. Se isso acontecer, você pode deixar todos os processos terminarem, o que deixará o site offline.&lt;/p&gt;

&lt;p&gt;Agora, vamos considerar o processo Sender, que é responsável pelo envio de e-mails. Ao contrário do processo de Repo , não é essencial conceder aos usuários acesso à sua conta bancária. Se o processo do Sender falhar por qualquer razão, não queremos encerrar a aplicação inteira. Queremos conter esta falha e deixar o resto do sistema continuar.&lt;/p&gt;

&lt;p&gt;Você pode isolar os acidentes configurando um processo para capturar as saídas. Capturar uma saída significa reconhecer a mensagem de saída de um processo vinculado, mas continuar a funcionar em vez de terminar. Isto também significa que a mensagem de saída não será propagada mais para outros processos. Voltando ao nosso exemplo original - se o Processo B estiver configurado para capturar as saídas, ele continuará funcionando após a queda do Processo C, mantendo o Processo A seguro também. Você pode configurar um processo para capturar saídas manualmente, mas normalmente você quer usar um tipo especial de processo chamado &lt;strong&gt;supervisor&lt;/strong&gt;. Vamos falar sobre &lt;strong&gt;supervisors&lt;/strong&gt; a seguir.&lt;/p&gt;

&lt;p&gt;Como você pode ver, as ligações de processo são um mecanismo essencial para detectar saídas e lidar com falhas inesperadas de processo. A maioria das funções de utilidade no módulo Task cria links de processo automaticamente, ligando-se ao processo atual, mas há algumas que não o fazem. Você tem a opção de ligar ou não ao processo atual, mas você tem que escolher a função correta.&lt;/p&gt;

&lt;p&gt;Por exemplo, quando usamos &lt;code&gt;async/1&lt;/code&gt; e &lt;code&gt;async_stream/3&lt;/code&gt;, foi criado um link de processo para cada novo processo. &lt;code&gt;Task.start/1&lt;/code&gt;, por outro lado, não cria um link de processo, mas existe o &lt;code&gt;Task.start_link/1&lt;/code&gt; que faz exatamente isso.&lt;/p&gt;

&lt;p&gt;A maioria das funções do módulo Task que se ligam ao processo atual por padrão têm uma função alternativa, geralmente terminando com &lt;code&gt;_nolink&lt;/code&gt;. &lt;code&gt;Task.Supervisor.async_nolink/3&lt;/code&gt; é a alternativa ao &lt;code&gt;Task.async/1&lt;/code&gt;. &lt;code&gt;Task.async_stream/3&lt;/code&gt; pode ser substituído pelo &lt;code&gt;Task.Supervisor.async_stream_nolink/4&lt;/code&gt;. Todas as funções no módulo &lt;strong&gt;Task.Supervisor&lt;/strong&gt; são projetados para serem ligados a um &lt;strong&gt;supervisor&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A seguir, vamos aprender sobre &lt;strong&gt;supervisors&lt;/strong&gt; e como podemos usar um quando iniciarmos processos de tarefas.&lt;/p&gt;




&lt;h1&gt;
  
  
  Conhecendo o Supervisor &lt;a&gt;
&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr97nr2ealbhc68j55ojr.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr97nr2ealbhc68j55ojr.gif" alt="Image description" width="400" height="293"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Assim como no local de trabalho, onde os supervisores são responsáveis por grupos de funcionários, os &lt;strong&gt;supervisors (supervisores)&lt;/strong&gt; de Elixir são responsáveis pelos processos a eles atribuídos. Os processos subordinados também são obrigados a se reportar a seu &lt;strong&gt;supervisor&lt;/strong&gt;, que tem que garantir que tudo esteja funcionando sem problemas. Para isso, os supervisors vêm com um conjunto de características que lhes permitem gerenciar de forma eficaz outros processos. &lt;strong&gt;Eles podem iniciar e interromper processos e reiniciá-los em caso de erros imprevistos no sistema&lt;/strong&gt;. Eles são configurados para capturar as saídas, assim, quando um processo supervisionado sai com um erro, esse erro será isolado e não se propagará mais. Tudo isso faz dos supervisors um importante bloco de construção para aplicações tolerantes a falhas.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs4dwrlmeuel1xbdoz850.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs4dwrlmeuel1xbdoz850.gif" alt="Image description" width="400" height="293"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Os processos supervisionados são chamados de &lt;strong&gt;child processes (processos filhos)&lt;/strong&gt;. Qualquer processo OTP pode ser supervisionado, e você também pode adicionar um supervisor como filho de outro supervisor. Tudo o que você tem que fazer é pedir ao supervisor que inicie o processo que você quer que seja gerenciado. Isto nos permite construir facilmente uma hierarquia de processos também chamada de &lt;strong&gt;supervision tree (árvore de supervisão)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Nossa aplicação sender já tem um supervisor no local, que você pode ver em &lt;code&gt;application.ex&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;Em &lt;code&gt;sender/lib/sender/application.ex&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;children&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="c1"&gt;# Starts a worker by calling: Sender.Worker.start_link(arg)&lt;/span&gt;
    &lt;span class="c1"&gt;# {Sender.Worker, arg}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="c1"&gt;# See https://hexdocs.pm/elixir/Supervisor.html&lt;/span&gt;
  &lt;span class="c1"&gt;# for other strategies and supported options&lt;/span&gt;
  &lt;span class="n"&gt;opts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;strategy:&lt;/span&gt; &lt;span class="ss"&gt;:one_for_one&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="no"&gt;Sender&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Supervisor&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="no"&gt;Supervisor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A função &lt;code&gt;start/2&lt;/code&gt; tem algum código padrão (boilerplate code) e algumas instruções já em vigor. No final da função temos &lt;code&gt;Supervisor.start_link(children, opts)&lt;/code&gt; que inicia o supervisor principal da aplicação. Como a variável children é apenas uma lista vazia, na verdade não há processos filhos para supervisionar. Esta configuração é o resultado de usarmos o argumento &lt;code&gt;--sup&lt;/code&gt; quando chamamos o comando &lt;code&gt;mix new&lt;/code&gt; para criar nosso projeto.&lt;/p&gt;

&lt;p&gt;Agora que você sabe como os supervisores são úteis, vamos ver como podemos usar um para nossos processos do módulo Task. Não queremos que nosso processo atual falhe se uma única tarefa falhar, então isolaremos erros potenciais iniciando os processos das tarefas sob um supervisor.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adicionando um Supervisor &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Elixir fornece um &lt;strong&gt;Supervisor behaviour&lt;/strong&gt; para criar processos de supervisão, que você mesmo tem que implementar. Entretanto, há também alguns supervisores embutidos que podemos usar sem escrever (quase) qualquer código, e um deles é o &lt;strong&gt;Task.Supervisor&lt;/strong&gt;. Ele é feito especificamente para trabalhar com processos de tarefas, por isso é uma excelente escolha para nós. Abra o &lt;code&gt;application.ex&lt;/code&gt; e atualize a lista de filhos:&lt;/p&gt;

&lt;p&gt;Em &lt;code&gt;sender/lib/sender/application.change1.ex&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;children&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Supervisor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="no"&gt;Sender&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;EmailTaskSupervisor&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="n"&gt;opts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;strategy:&lt;/span&gt; &lt;span class="ss"&gt;:one_for_one&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="no"&gt;Sender&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Supervisor&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="no"&gt;Supervisor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O elemento que acrescentamos é referido como um &lt;strong&gt;child specification (especificação de filho). Existem diferentes tipos de formatos para escrever __child specifications&lt;/strong&gt;, mas na maioria das vezes é um tuple, contendo informações sobre o processo do filho. Esta informação é usada pelo supervisor para identificar, iniciar e ligar o processo.&lt;/p&gt;

&lt;p&gt;Como o &lt;strong&gt;Task.Supervisor&lt;/strong&gt; é um módulo incorporado, nosso &lt;strong&gt;child specification&lt;/strong&gt; é simplesmente o nome do módulo, seguido por uma lista de opções. Usamos a opção &lt;code&gt;:name&lt;/code&gt; para dar-lhe um nome único de nossa escolha, que usaremos mais tarde. Nomear um processo é conhecido como &lt;strong&gt;name registration (registro de nome)&lt;/strong&gt;. É comum anexar &lt;strong&gt;"Supervisor"&lt;/strong&gt; ao nomear supervisores, por isso o chamamos &lt;code&gt;Sender.EmailTaskSupervisor&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;O &lt;strong&gt;child specification&lt;/strong&gt; também poderia ser um map. Podemos reescrever a última mudança e usar um map como este:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;children&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;%{&lt;/span&gt;
      &lt;span class="ss"&gt;id:&lt;/span&gt; &lt;span class="no"&gt;Sender&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;EmailTaskSupervisor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="ss"&gt;start:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Supervisor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;:start_link&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="no"&gt;Sender&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;EmailTaskSupervisor&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="n"&gt;opts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;strategy:&lt;/span&gt; &lt;span class="ss"&gt;:one_for_one&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="no"&gt;Sender&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Supervisor&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="no"&gt;Supervisor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usar um map é mais verboso, mas permite definir outras opções de configuração no map, além dos valores &lt;code&gt;:id&lt;/code&gt; e &lt;code&gt;:start&lt;/code&gt;. Há também uma função de ajuda &lt;code&gt;Supervisor.child_spec/1²&lt;/code&gt; que retorna um map e permite que você sobreponha apenas as chaves que você precisa.&lt;/p&gt;

&lt;p&gt;Vamos manter o formato tuple por enquanto, mas os outros formatos também são abordados no livro &lt;strong&gt;Concurrent Data Processing in Elixir&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Nosso supervisor está agora pronto para uso. É tão simples quanto isso, e não há necessidade de criar nenhum arquivo ou escrever mais código. Esta simples mudança nos permite usar toda uma série de funções encontradas no módulo &lt;strong&gt;Task.Supervisor&lt;/strong&gt;, algumas das quais introduzimos anteriormente.&lt;/p&gt;

&lt;h3&gt;
  
  
  Usando Task.Supervisor &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Antes de passarmos a usar o &lt;strong&gt;EmailTaskSupervisor&lt;/strong&gt;, vamos ver o que acontece quando ocorre um erro e não há supervisor no local. Vamos simular um erro, levantando uma exceção ao enviar um de nossos e-mails falsos. Edite &lt;code&gt;sender.ex&lt;/code&gt; e adicione a seguinte cláusula de função pouco antes de &lt;code&gt;enviar_email/1&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;Em &lt;code&gt;sender/lib/sender.change4.ex&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;send_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"konnichiwa@world.com"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="s2"&gt;"Oops, couldn't send email to &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;!"&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;send_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
 &lt;span class="no"&gt;Process&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Email to &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; sent"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"email_sent"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usando pattern matching, vamos abrir uma exceção somente quando o endereço de e-mail for &lt;code&gt;konnichiwa@world.com&lt;/code&gt;. Vamos ver o impacto deste erro na prática. Reinicie seu IEx shell e execute a função embutida &lt;code&gt;self/0&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&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="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;#PID&amp;lt;0.136.0&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você obtém um identificador de processo para o processo atual, que é o própria shell do IEx. Seu número pode ser diferente do meu, mas tudo bem. Tome nota disso. &lt;/p&gt;

&lt;p&gt;Agora, vamos executar nossa função &lt;code&gt;notify_all/1&lt;/code&gt; e ver o que acontece:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&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="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Sender&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;notify_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;emails&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="no"&gt;Task&lt;/span&gt; &lt;span class="c1"&gt;#PID&amp;lt;0.154.0&amp;gt; started from #PID&amp;lt;0.136.0&amp;gt; terminating&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;RuntimeError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="no"&gt;Oops&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;couldn&lt;/span&gt;&lt;span class="s1"&gt;'t send email to konnichiwa@world.com!
 (sender) lib/sender.ex:8: Sender.send_email/1
 (elixir) lib/task/supervised.ex:90: Task.Supervised.invoke_mfa/2
 (elixir) lib/task/supervised.ex:35: Task.Supervised.reply/5
 (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
Function: &amp;amp;:erlang.apply/2
Args: [#Function&amp;lt;0.104978293/1 in Sender.notify_all/1&amp;gt;,
["konnichiwa@world.com"]]
** (EXIT from #PID&amp;lt;0.136.0&amp;gt;) shell process exited with reason:
an exception was raised:
  ** (RuntimeError) Oops, couldn'&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="n"&gt;send&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;konnichiwa&lt;/span&gt;&lt;span class="nv"&gt;@world&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com!&lt;/span&gt;
   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="ss"&gt;ex:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Sender&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send_email&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="n"&gt;elixir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;supervised&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="ss"&gt;ex:&lt;/span&gt;&lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Supervised&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke_mfa&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;elixir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;supervised&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="ss"&gt;ex:&lt;/span&gt;&lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Supervised&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reply&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;
   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdlib&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;proc_lib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="ss"&gt;erl:&lt;/span&gt;&lt;span class="mi"&gt;249&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="ss"&gt;:proc_lib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;init_p_do_apply&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="n"&gt;iex&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="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essa é uma grande mensagem de erro. Na verdade, há duas mensagens de erro que parecem ser quase idênticas. Lembra-se do que dissemos sobre as ligações de processos e como as falhas se propagam entre processos interligados? Neste caso, um processo de tarefa vinculado ao IEx levanta uma exceção. Devido a este link, criado pelo async_stream/3 , o IEx também trava com a mesma mensagem de exceção. Você pode verificar isto executando &lt;code&gt;self()&lt;/code&gt; novamente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&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="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;#PID&amp;lt;0.155.0&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Temos um novo identificador de processo, o que significa que um novo processo IEx foi iniciado e o antigo se quebrou. &lt;/p&gt;

&lt;p&gt;Podemos evitar isto usando o novo &lt;code&gt;EmailTaskSupervisor&lt;/code&gt;. Alterar &lt;code&gt;notify_all/1&lt;/code&gt; para usar &lt;code&gt;Task.Supervisor.async_stream_nolink/4&lt;/code&gt; em vez de &lt;code&gt;Task.async_stream/3&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;Em &lt;code&gt;sender/lib/sender.change4.ex&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;notify_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;emails&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="no"&gt;Sender&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;EmailTaskSupervisor&lt;/span&gt;
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Supervisor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;async_stream_nolink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;emails&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;send_email&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="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_list&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O novo código é muito parecido com o antigo. O primeiro argumento de &lt;code&gt;async_stream_nolink/4&lt;/code&gt; é um módulo supervisor para os processos de tarefa - é onde você pode usar &lt;code&gt;Sender.EmailTaskSupervisor&lt;/code&gt;. O resto dos argumentos são idênticos ao &lt;code&gt;Task.async_stream/3&lt;/code&gt;. Vamos executar &lt;code&gt;recompile()&lt;/code&gt; e &lt;code&gt;notificar_tudo/1&lt;/code&gt; novamente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Sender&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;notify_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;emails&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="no"&gt;Task&lt;/span&gt; &lt;span class="c1"&gt;#PID&amp;lt;0.173.0&amp;gt; started from #PID&amp;lt;0.155.0&amp;gt; terminating&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;RuntimeError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="no"&gt;Oops&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;couldn&lt;/span&gt;&lt;span class="s1"&gt;'t send email to konnichiwa@world.com!
  (sender) lib/sender.ex:8: Sender.send_email/1
  (elixir) lib/task/supervised.ex:90: Task.Supervised.invoke_mfa/2
  (elixir) lib/task/supervised.ex:35: Task.Supervised.reply/5
  (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
Function: &amp;amp;:erlang.apply/2
Args: [#Function&amp;lt;0.32410907/1 in Sender.notify_all/1&amp;gt;,
["konnichiwa@world.com"]]
[info] Email to hello@world.com sent
[info] Email to hola@world.com sent
[info] Email to nihao@world.com sent
[
  ok: {:ok, "email_sent"},
  ok: {:ok, "email_sent"},
  ok: {:ok, "email_sent"},
  exit: {%RuntimeError{
    message: "Oops, couldn'&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="n"&gt;send&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;konnichiwa&lt;/span&gt;&lt;span class="nv"&gt;@world&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com!&lt;/span&gt;&lt;span class="s2"&gt;"
  },
  [
    {Sender, :send_email, 1, [file: 'lib/sender.ex', line: 8]},
    {Task.Supervised, :invoke_mfa, 2,
      [file: 'lib/task/supervised.ex', line: 90]},
    {Task.Supervised, :reply, 5, [file: 'lib/task/supervised.ex', line: 35]},
    {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 249]}
  ]}
]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A exceção familiar ainda está impressa, mas desta vez obtivemos um resultado significativo. Podemos ver que todas as tarefas foram concluídas com sucesso, exceto uma. A tarefa que se quebrou retornou um tuple &lt;code&gt;:exit&lt;/code&gt; contendo a mensagem de erro e até mesmo um traço de pilha. O mais importante é que nosso processo atual foi isolado do acidente - você pode verificar isso executando o &lt;code&gt;self()&lt;/code&gt; novamente. &lt;/p&gt;

&lt;p&gt;É fácil ver que esta é uma enorme melhoria em relação a nossa versão anterior. O supervisor que introduzimos trata de processos e erros simultâneos, enquanto ainda estamos colhendo os benefícios de desempenho do &lt;code&gt;async_stream&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Você já deve ter ouvido falar de uma filosofia associada a Erlang chamada &lt;strong&gt;Let It Crash (deixe falhar)&lt;/strong&gt;. As aplicações Erlang podem se recuperar rapidamente de erros reiniciando partes de seu sistema. Elixir também adota esta filosofia. Infelizmente, esta abordagem também é freqüentemente mal compreendida. Na próxima seção vamos explicar o que realmente significa &lt;strong&gt;Let It Crash&lt;/strong&gt; e como os supervisores podem reiniciar processos para tornar nossos sistemas ainda mais resilientes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Entendendo o Let it Crash &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Usamos o &lt;strong&gt;Task.Supervisor&lt;/strong&gt; para isolar uma falha de processo, mas pode parecer estranho que não tenhamos evitado a falha simplesmente adicionando o tratamento de erros na função &lt;code&gt;send_email/1&lt;/code&gt;. Neste caso específico, fizemos isso de propósito, apenas para simular uma exceção inesperada. Na prática, você deve providenciar o tratamento de erros quando espera que um erro ocorra, e deixar o resto para o supervisor como último recurso.&lt;/p&gt;

&lt;p&gt;Ao discutir o tratamento de erros para o Elixir, a frase &lt;strong&gt;let it crash&lt;/strong&gt; é freqüentemente usada. Como resultado, algumas pessoas assumem que &lt;strong&gt;let it crash&lt;/strong&gt; significa que Erlang e os desenvolvedores Elixir não fazem nenhuma manipulação de erros, o que não é o caso. A correspondência de padrões e as macro em Elixir facilitam o trabalho com {:ok, resultado} e {:erro, msg} tuples, e esta abordagem é amplamente utilizada na comunidade. Elixir também tem &lt;code&gt;try&lt;/code&gt; e &lt;code&gt;rescue&lt;/code&gt; para capturar exceções, semelhante à &lt;code&gt;try&lt;/code&gt; e &lt;code&gt;catch&lt;/code&gt; em outras linguagens.&lt;/p&gt;

&lt;p&gt;Entretanto, por mais que tentemos como engenheiros, sabemos que erros podem acontecer. Isto muitas vezes leva a algo chamado &lt;strong&gt;Defensive programming (programação defensiva)&lt;/strong&gt;. Ela descreve a prática de tentar incessantemente cobrir todos os cenários possíveis de falha, mesmo quando alguns cenários são muito improváveis de acontecer, e não vale a pena lidar com eles.&lt;/p&gt;

&lt;p&gt;Erlang e Elixir adotam uma abordagem diferente para a programação defensiva. Como todo código é executado em processos e processos que são leves, eles se concentram em como o sistema pode se recuperar de falhas versus como evitar todas as falhas. Você pode optar por permitir que uma parte (ou mesmo o todo) da aplicação se quebre e reinicie, mas você mesmo tratará dos outros erros. Esta mudança no pensamento e no projeto do software é a razão pela qual Erlang ficou famoso por sua confiabilidade e escalabilidade.&lt;/p&gt;

&lt;p&gt;É aí que entram em jogo os supervisores. Vimos que os supervisores podem isolar as colisões, mas também podem reiniciar os processos filhos. Há três valores diferentes de reinicialização disponíveis para nós:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;:temporary&lt;/em&gt; nunca reiniciará os processos filhos. &lt;/li&gt;
&lt;li&gt;
&lt;em&gt;:transient&lt;/em&gt; reiniciará os processos filhos, mas somente quando eles terminam com um erro. &lt;/li&gt;
&lt;li&gt;
&lt;em&gt;:permanent&lt;/em&gt; reinicia sempre os filhos, mantendo-os em funcionamento, mesmo quando elas tentam desligar-se sem um erro.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;ℹ️ Esclarecimento sobre a terminologia utilizada&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A palavra &lt;strong&gt;reinício/restart&lt;/strong&gt; é um pouco enganosa no contexto dos processos em Elixir. Uma vez que um processo termina, ele não pode ser trazido de volta à vida. Portanto, reiniciar um processo resulta em &lt;strong&gt;iniciar um novo processo para tomar o lugar do antigo&lt;/strong&gt;, usando a mesma child especification.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Dependendo da freqüência do acidente, o próprio supervisor também pode terminar quando um processo filho não puder ser recuperado. Lembre-se de que a responsabilidade do supervisor é de zelar por seus processos. Se for usado um valor de restart &lt;code&gt;:transient&lt;/code&gt; ou &lt;code&gt;:permanent&lt;/code&gt; e um processo continuar a falhar, o supervisor irá sair, porque falhou em reiniciar esse processo. Isso é discutido com mais detalhes no livro Concurrent Data Processing in Elixir no Capítulo 2, Processos de Longa Duração Usando o GenServer, na página 25.&lt;/p&gt;

&lt;p&gt;O &lt;strong&gt;Task.Supervisor&lt;/strong&gt; incorporado que usamos até agora já está usando o valor de reinício &lt;code&gt;:temporary&lt;/code&gt; para processos filhos. Este é um padrão sensato, pois evita que todos os processos de tarefas se quebrem se outra tarefa sair com um erro. No entanto, estas opções serão úteis no próximo capítulo do livro quando é construido árvores de supervisão mais complexas.&lt;/p&gt;




&lt;h1&gt;
  
  
  Conclusão &lt;a&gt;
&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;Cobrimos os processos do Elixir e usamos o módulo Task para fazer o trabalho concorrentemente e em paralelo, evitando facilmente erros de timeout e exceções inesperadas. Você também aprendeu sobre supervisores, que são a base da construção de aplicações Elixir tolerantes a falhas.&lt;/p&gt;

&lt;p&gt;Embora o módulo Task seja muito poderoso e versátil, ele só é útil para executar funcões concorrentes ocasionais. Como resultado, os processos do módulo Task tem vida curta, vivem e terminam assim que são concluídos. No próximo capítulo do livro, é introduzido outro tipo de processo, que é capaz de funcionar e manter o estado durante o tempo que for necessário. Vai mudar completamente o jeito como você constrói aplicações para sempre, e isto não é um exagero.&lt;/p&gt;

&lt;p&gt;O próximo capítulo do livro fala sobre GenServer e você pode continuar lendo nele, ou quem sabe em um próximo post por aqui mesmo...&lt;/p&gt;

&lt;p&gt;até logo 🙂&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>concurrency</category>
      <category>braziliandevs</category>
      <category>erlang</category>
    </item>
    <item>
      <title>💻 Olá mundo da programação concorrente</title>
      <dc:creator>Dev Maiqui 🇧🇷</dc:creator>
      <pubDate>Fri, 24 Jun 2022 20:44:36 +0000</pubDate>
      <link>https://forem.com/maiquitome/ola-mundo-da-programacao-concorrente-57mp</link>
      <guid>https://forem.com/maiquitome/ola-mundo-da-programacao-concorrente-57mp</guid>
      <description>&lt;p&gt;Nest post vamos dar uma introdução sobre a programação concorrente. Vamos abordar também um pouco sobre a diferença entre &lt;strong&gt;concorrência&lt;/strong&gt; e &lt;strong&gt;paralelismo&lt;/strong&gt;, assuntos que podem parecer sinônimos, mas quando falamos em programação de computadores há diferenças.&lt;/p&gt;

&lt;p&gt;Neste post foram abordados os assuntos principais de cada pesquisa feita. Para mais detalhes sugiro a leitura ou visualização delas:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Site da Intel;&lt;/li&gt;
&lt;li&gt;Livro C++ Concurrency in Action;&lt;/li&gt;
&lt;li&gt;Livro Erlang and OTP in Action;&lt;/li&gt;
&lt;li&gt;Vídeo &lt;a href="https://bit.ly/3Qk9vIJ" rel="noopener noreferrer"&gt;O que são os NÚCLEOS, THREADS, DUO, QUAD?&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Artigo &lt;a href="https://bit.ly/3zYBEiG" rel="noopener noreferrer"&gt;Concurrency vs Parallelism&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Artigo &lt;a href="https://bit.ly/3nbJ2zF" rel="noopener noreferrer"&gt;Threads: O que são e para que servem em um processador?&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;ul&gt;
&lt;li&gt;O que é concorrência?&lt;/li&gt;
&lt;li&gt;
Concorrência em sistemas de computador

&lt;ul&gt;
&lt;li&gt;Núcleos vs. Threads&lt;/li&gt;
&lt;li&gt;Hyper-threading (threads adicionais)&lt;/li&gt;
&lt;li&gt;Alternância de Tarefas (Task Switching)&lt;/li&gt;
&lt;li&gt;Execução Paralela&lt;/li&gt;
&lt;li&gt;Alternância de Tarefas vs. Execução Paralela&lt;/li&gt;
&lt;li&gt;Execução paralela e concorrente&lt;/li&gt;
&lt;li&gt;Assíncrono X Síncrono&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Abordagens à concorrência

&lt;ul&gt;
&lt;li&gt;Concorrência com múltiplos processos&lt;/li&gt;
&lt;li&gt;Concorrência com múltiplos threads&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

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

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://go.hotmart.com/R93865620U" rel="noopener noreferrer"&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%2Fpkoqkmh9hic17tnddjf6.png" alt="A Jornada do Autodidata em Inglês"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  O que é concorrência? &lt;a&gt;
&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;Conforme o livro &lt;strong&gt;C++ Concurrency in Action&lt;/strong&gt; a &lt;strong&gt;concorrência&lt;/strong&gt; é sobre duas, ou mais &lt;strong&gt;atividades separadas/independentes&lt;/strong&gt; que acontecem &lt;strong&gt;ao mesmo tempo&lt;/strong&gt;. Encontramos a concorrência como parte natural da vida; podemos caminhar e falar ao mesmo tempo, ou realizar ações diferentes com cada mão, e &lt;strong&gt;cada um pode viver a sua vida independentemente do outro&lt;/strong&gt; - você pode ver futebol enquanto eu vou nadar, e assim por diante.&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%2Fsol2k2xy3tbamt5vfyp1.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%2Fsol2k2xy3tbamt5vfyp1.gif" alt="Image description"&gt;&lt;/a&gt; &lt;/p&gt;




&lt;h1&gt;
  
  
  Concorrência em sistemas de computador &lt;a&gt;
&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;Quando falamos de concorrência em computadores, nos referimos a um único sistema que executa múltiplas atividades &lt;strong&gt;independentes&lt;/strong&gt; ao mesmo tempo e sem ordem específica, em vez de sequencialmente (ordem específica).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;em&gt;Sequencialmente (ordem específica):&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%2F6lq0llmcctbzsxl9zaes.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%2F6lq0llmcctbzsxl9zaes.gif" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Em um jogo de cartas, os jogadores jogam ao mesmo tempo, mas o jogo começa com o baralho sendo embaralhado, as cartas sendo entregues aos jogadores e, depois, cada jogador joga na sua vez, há uma ordem especifica:&lt;br&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%2F1z92ds8aed69se0ns0ix.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%2F1z92ds8aed69se0ns0ix.gif" alt="Image description"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;em&gt;Ao mesmo tempo e sem ordem específica:&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%2F573snicm4hdibo376fbn.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%2F573snicm4hdibo376fbn.gif" alt="Image description"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Definição do livro &lt;strong&gt;Erlang and OTP in Action&lt;/strong&gt;: &lt;/p&gt;

&lt;p&gt;Concorrência é apenas mais uma palavra para paralelo? Quase, mas não exatamente, pelo menos quando estamos falando de computadores e programação.&lt;/p&gt;

&lt;p&gt;Uma definição semiformal popular diz algo como: "Aquelas coisas que não têm nada que as obrigue a acontecer em uma ordem específica são ditas como concorrentes". Por exemplo, dada a tarefa de ordenar dois baralhos de cartas, você poderia ordenar um baralho primeiro e depois o outro; ou se você tivesse braços e olhos extras, você poderia ordenar ambos em paralelo. Nada exige que você os faça em uma determinada ordem; portanto, são tarefas concorrentes. Elas podem ser feitas em qualquer ordem, ou você pode pular para frente e para trás entre as tarefas até que ambas sejam feitas; ou, se você tiver os recursos extras (ou talvez alguém para ajudá-lo), você pode executá-las simultaneamente de forma verdadeiramente paralela.&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%2Fkogmcmwnpa1uzg733grh.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%2Fkogmcmwnpa1uzg733grh.gif" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Isto pode soar estranho: não deveríamos dizer que as tarefas só são concorrentes se elas estão acontecendo ao mesmo tempo? Bem, a questão com essa definição é que elas podem acontecer ao mesmo tempo, e nós somos livres para agendá-las de acordo com nossa conveniência. Tarefas que precisam ser feitas simultaneamente não são tarefas separadas, enquanto algumas tarefas são separadas mas não concorrentes e devem ser feitas em ordem, como quebrar o ovo antes de fazer a omelete. As demais são concorrentes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Núcleos vs. Threads &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Conforme o site da Intel, um thread, ou thread de execução, é um termo de software para a &lt;strong&gt;sequência&lt;/strong&gt; básica &lt;strong&gt;ordenada&lt;/strong&gt; de instruções que pode ser passada ou processada por um &lt;strong&gt;único núcleo/core de CPU&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Single thread&lt;/strong&gt;: Cada core corresponde à um thread;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi thread (Hyper-threading)&lt;/strong&gt;: Cada core possui mais de um thread.&lt;/li&gt;
&lt;/ul&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%2Fen5hgk383wayz2oah0rj.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%2Fen5hgk383wayz2oah0rj.png" alt="Image description"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Créditos da imagem acima: &lt;a href="https://www.mobilebit.com.br/tecnologia/2020/12/15/threads-o-que-sao-para-que-servem-em-um-processador/" rel="noopener noreferrer"&gt;https://www.mobilebit.com.br/tecnologia/2020/12/15/threads-o-que-sao-para-que-servem-em-um-processador/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Hyper-threading (threads adicionais) &lt;a&gt;
&lt;/a&gt;
&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%2F5to4bl1i8wape4sum1ls.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%2F5to4bl1i8wape4sum1ls.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;As Threads adicionais são conhecidas popularmente como núcleos lógicos ou núcleos virtuais. &lt;/li&gt;
&lt;li&gt;As Threads adicionais não tem o mesmo poder de processamento de um núcleo físico (thread real).&lt;/li&gt;
&lt;li&gt;As Threads adicionais vão ajudar em softwares que não conseguem lidar com vários núcleos físicos.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Em um processador de &lt;strong&gt;quatro núcleos e oito threads&lt;/strong&gt;, como é o caso do processador &lt;a href="https://intel.ly/3mUAb5j" rel="noopener noreferrer"&gt;Intel Core i7-1165G7&lt;/a&gt; você verá em um sistema Linux no &lt;strong&gt;Monitor do Sistema&lt;/strong&gt; oito gráficos representando os núcleos, ou seja, oito linhas de execução (threads) - quatro núcleos físicos e quatro núcleos virtuais.&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%2Fvwzv4ej9jiuhrqfooc50.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%2Fvwzv4ej9jiuhrqfooc50.png" alt="Image description"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Veja no site as especificações do processador &lt;a href="https://intel.ly/3mUAb5j" rel="noopener noreferrer"&gt;Intel Core i7-1165G7&lt;/a&gt;&lt;br&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%2Fzu7oglymdtfqfdxfbch2.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%2Fzu7oglymdtfqfdxfbch2.png" alt="Image description"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://go.hotmart.com/H93763859E" rel="noopener noreferrer"&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%2Fisxopdurvofcx18iptvb.png" alt="Formação TS"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Alternância de Tarefas (Task Switching / Context Switching) &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Executando mais de uma tarefa ao mesmo tempo, mas não de forma paralela.&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%2Fcm0bmjudhpfrtbdk5ees.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%2Fcm0bmjudhpfrtbdk5ees.gif" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Alternância de tarefas&lt;/strong&gt; em uma máquina com &lt;strong&gt;um só núcleo&lt;/strong&gt; e &lt;strong&gt;um só thread&lt;/strong&gt;:&lt;br&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%2Fmeus5e59m0urxucgxnqf.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%2Fmeus5e59m0urxucgxnqf.png" alt="Image description"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Historicamente, a maioria dos computadores de mesa (desktop) tiveram um processador, com uma &lt;strong&gt;única unidade de processamento ou núcleo (single core processor)&lt;/strong&gt;. Tal máquina só pode executar uma tarefa de cada vez, mas pode alternar entre tarefas muitas vezes por segundo. Ao fazer um pouco de uma tarefa e depois um pouco de outra e assim por diante, parece que as tarefas acontecem simultaneamente. Isto chama-se &lt;strong&gt;alternância de tarefas (task switching)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Exemplos de processadores single core:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://intel.ly/3xDDyUp" rel="noopener noreferrer"&gt;Intel Celeron G440&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Frequência baseada em processador: 1.60 GHz &lt;/li&gt;
&lt;li&gt;Nº de threads: 1&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;a href="https://intel.ly/3zu0J4Y" rel="noopener noreferrer"&gt;Intel Celeron G470&lt;/a&gt; 

&lt;ul&gt;
&lt;li&gt;Frequência baseada em processador: 2.00 GHz &lt;/li&gt;
&lt;li&gt;Nº de threads: 2&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Execução paralela &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Executando mais de uma tarefa ao mesmo tempo e de forma paralela (lado a lado).&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%2F3cr9fe8bhehftlje6y4y.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%2F3cr9fe8bhehftlje6y4y.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Créditos da imagem acima: &lt;a href="https://jenkov.com/" rel="noopener noreferrer"&gt;https://jenkov.com/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Computadores contendo múltiplos processadores têm sido utilizados para servidores e tarefas de computação de alto desempenho durante anos, e computadores baseados em &lt;strong&gt;processadores com mais do que um núcleo num único chip (multicore processors)&lt;/strong&gt; tornam-se cada vez mais comuns em máquinas ‘desktop’. Quer tenham processadores múltiplos ou núcleos múltiplos dentro de um processador (ou ambos), estes computadores conseguem executar genuinamente mais do que uma tarefa em paralelo.&lt;/p&gt;

&lt;p&gt;Exemplos de processadores multi core:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://intel.ly/3zy0k1j" rel="noopener noreferrer"&gt;Intel Core i7-12650HX (12ª Geração)&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Nº de núcleos: 14&lt;/li&gt;
&lt;li&gt;Frequência turbo max: 4.70 GHz&lt;/li&gt;
&lt;li&gt;Nº de thrFrequência baseada em processadoreads 20&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;a href="https://intel.ly/3trgFB6" rel="noopener noreferrer"&gt;Intel Core i9-12900HX (12ª Geração)&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Nº de núcleos: 16&lt;/li&gt;
&lt;li&gt;Frequência turbo max: 5.00 GHz&lt;/li&gt;
&lt;li&gt;Nº de threads 24&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;a href="https://intel.ly/3xH0lP4" rel="noopener noreferrer"&gt;Intel Xeon Platinum 8362 (3ª Geração)&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Nº de núcleos: 32&lt;/li&gt;
&lt;li&gt;Frequência turbo max: 3.60 GHz&lt;/li&gt;
&lt;li&gt;Frequência baseada em processador: 2.80 GHz&lt;/li&gt;
&lt;li&gt;Nº de threads: 64&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;a href="https://intel.ly/3zvTwkK" rel="noopener noreferrer"&gt;Intel Xeon Platinum 8380 (3ª Geração)&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Nº de núcleos: 40&lt;/li&gt;
&lt;li&gt;Frequência turbo max: 3.40 GHz&lt;/li&gt;
&lt;li&gt;Frequência baseada em processador: 2.30 GHz&lt;/li&gt;
&lt;li&gt;Nº de threads: 80&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Alternância de Tarefas vs. Execução Paralela &lt;a&gt;
&lt;/a&gt;
&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%2Ffzhm1ctgmuiyefdzox6s.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%2Ffzhm1ctgmuiyefdzox6s.png" alt="Alternância de Tarefas vs. Execução Paralela"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Créditos da imagem acima: Livro C++ Concurrency in Action.&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%2F9ukmgjtfd3r8mo7uwi93.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%2F9ukmgjtfd3r8mo7uwi93.gif" alt="GIF Concurrency vs Parallelism"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A Figura 1.1 mostra um cenário idealizado de um computador com precisamente &lt;strong&gt;duas tarefas&lt;/strong&gt; a fazer, cada uma dividida em 10 blocos de igual tamanho. Numa máquina de núcleo duplo (com dois núcleos de processamento), cada tarefa pode executar no seu próprio núcleo. Numa máquina de núcleo único que faz a troca de tarefas (task switching), os blocos de cada tarefa são intercalados. Mas também são espaçados um pouco (na figura 1.1, isto é mostrado pelas barras cinzentas que separam os blocos sendo mais espessas do que as barras separadoras mostradas para a máquina de núcleo duplo); para fazer a intercalação, o sistema tem de executar uma troca de contexto cada vez que muda de uma tarefa para outra, e isto leva tempo. Para executar uma mudança de contexto, o sistema operacional tem de guardar o estado da CPU e o ponteiro de instruções para a tarefa atualmente em execução, determinar para qual tarefa mudar, e recarregar o estado da CPU para a tarefa para a qual é mudada. A CPU terá então potencialmente de carregar a memória para as instruções e os dados para a nova tarefa na &lt;strong&gt;memória transitória (cache)&lt;/strong&gt;, o que pode impedir a CPU de executar quaisquer instruções, causando mais atrasos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Execução paralela e concorrente &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Executando mais de uma tarefa ao mesmo tempo mas não de forma paralela em cada CPU e as duas CPUs trabalhando de forma paralela.&lt;/p&gt;

&lt;p&gt;Em uma CPU acontece a alternância de tarefas, ou seja, uma tarefa deve parar para a outra prosseguir. As duas CPUs estão trabalhando em paralelo (lado a lado), ou seja, uma CPU não precisar parar para a outra prosseguir.&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%2F6xc6bmncecyp19n5xt8y.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%2F6xc6bmncecyp19n5xt8y.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Créditos da imagem acima: Livro C++ Concurrency in Action.&lt;/p&gt;

&lt;p&gt;Embora a disponibilidade de concorrência no hardware seja mais óbvia com sistemas multiprocessadores ou multinúcleo, alguns processadores podem executar &lt;strong&gt;vários fios (threads) num único núcleo (Hyper-threading)&lt;/strong&gt;. O fator importante a considerar é o número de fios do hardware, sendo a medida de quantas tarefas independentes o hardware pode genuinamente executar concorrentemente. Mesmo com um sistema com uma concorrência genuína de hardware, é fácil ter mais tarefas do que o hardware pode executar em paralelo, por isso a alternância de tarefas continua a ser utilizada nestes casos. Por exemplo, num computador ‘desktop’ típico pode haver centenas de tarefas em execução, executando operações em segundo plano (background), mesmo quando o computador está nominalmente inativo. É a alternância de tarefas que permite executar estas tarefas em segundo plano e executar o processador de texto, compilador, editor, e browser da web (ou qualquer combinação de aplicações) tudo de uma só vez. A Figura 1.2 mostra a alternância de tarefas entre quatro tarefas numa máquina dual-core, mais uma vez para um cenário idealizado com as tarefas divididas ordenadamente em blocos de igual tamanho.&lt;/p&gt;

&lt;p&gt;Podemos também ter uma divisão de uma única tarefa em subtarefas que podem ser executadas concorrentemente e em paralelo.&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%2F057kjjd08wmftrhd50ic.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%2F057kjjd08wmftrhd50ic.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Créditos da imagem acima: &lt;a href="https://jenkov.com/" rel="noopener noreferrer"&gt;https://jenkov.com/&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Conforme o livro &lt;strong&gt;C++ Concurrency in Action&lt;/strong&gt; a concorrência e o paralelismo têm significados amplamente sobrepostos no que diz respeito ao código multithreaded. De fato, para muitos eles significam a mesma coisa. A diferença é principalmente uma questão de nuance, foco e intenção. Ambos os termos são sobre executar múltiplas tarefas simultaneamente, usando o hardware disponível, mas &lt;strong&gt;o paralelismo é muito mais orientado para o desempenho&lt;/strong&gt;. As pessoas falam em paralelismo quando sua principal preocupação é aproveitar o hardware disponível para aumentar o desempenho do processamento de dados em massa, enquanto as pessoas falam em concorrência quando sua principal preocupação é a separação de preocupações, ou capacidade de resposta.&lt;/p&gt;

&lt;h3&gt;
  
  
  Assíncrono X Síncrono &lt;a&gt;
&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Podemos encontrar a palavra &lt;code&gt;async&lt;/code&gt; (asynchronous = assíncrono) como uma palavra reservada em linguagens de programação para converter código sequencial em código concorrente, como na linguagem Elixir com o &lt;a href="https://hexdocs.pm/elixir/1.13/Task.html" rel="noopener noreferrer"&gt;Task.async&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Tanto o código Síncrono como Assíncrono são executados aos mesmo tempo, a diferença é que o código assíncrono não há uma ordem específica e por isso é considerado concorrente:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Assíncrono&lt;/strong&gt; = ao mesmo tempo = velocidades diferentes = sem ordem específica = concorrente:&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%2Fzx3ifhmuoc2vnse9kwf0.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%2Fzx3ifhmuoc2vnse9kwf0.gif" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Síncrono&lt;/strong&gt; = ao mesmo tempo = velocidades iguais = ordem específica = não concorrente:&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%2Fnt7561sg72p1itlu8rqo.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%2Fnt7561sg72p1itlu8rqo.gif" alt="Image description"&gt;&lt;/a&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%2Fjy0ecxof6fus6u35v2si.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%2Fjy0ecxof6fus6u35v2si.gif" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Concorrência com múltiplos processos &lt;a&gt;
&lt;/a&gt;
&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%2Fh2kyp7ssbwlv0pzvrqc2.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%2Fh2kyp7ssbwlv0pzvrqc2.png" alt="Image description"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Créditos da imagem acima: Livro C++ Concurrency in Action. &lt;/p&gt;

&lt;p&gt;A primeira maneira de fazer uso da concorrência dentro de uma aplicação é dividir a aplicação em múltiplos processos separados, em uma única thread, que são executados ao mesmo tempo, da mesma forma que você pode executar seu navegador web e processador de texto ao mesmo tempo. Estes processos separados podem então passar mensagens uns para os outros através de todos os canais normais de comunicação interprocessados (signals, sockets, files, pipes, etc.), como mostrado na figura 1.3. Uma desvantagem é que tal comunicação entre processos é muitas vezes complicada de configurar ou lenta, ou ambos, porque os sistemas operacionais normalmente fornecem muita proteção entre processos para evitar que um processo modifique acidentalmente os dados pertencentes a outro processo. Outra desvantagem é que há uma sobrecarga inerente na execução de múltiplos processos: leva tempo para iniciar um processo, a operação deve dedicar recursos internos ao gerenciamento do processo, e assim por diante.&lt;/p&gt;

&lt;p&gt;Nem tudo é negativo: a proteção adicional que os sistemas operacionais normalmente proporcionam entre os processos e os mecanismos de comunicação de nível superior significa que pode ser mais fácil escrever código concorrente seguro com os processos do que com as threads. De fato, ambientes como o fornecido pela linguagem de programação Erlang (&lt;a href="http://www.erlang.org/" rel="noopener noreferrer"&gt;www.erlang.org/&lt;/a&gt;) utilizam processos como o bloco fundamental da concorrência com grande efeito.&lt;/p&gt;

&lt;p&gt;A utilização de processos separados para a concorrência também tem uma vantagem adicional - você pode executar os processos separados em máquinas distintas conectadas através de uma rede. Embora isto aumente o custo de comunicação, em um sistema cuidadosamente projetado pode ser uma forma econômica de aumentar o paralelismo disponível e melhorar o desempenho.&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%2Fwzmhbnw1omkdjb4ez0zh.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%2Fwzmhbnw1omkdjb4ez0zh.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Créditos da imagem acima: Livro Erlang and OTP in Action.&lt;/p&gt;

&lt;h3&gt;
  
  
  Concorrência com múltiplos threads &lt;a&gt;
&lt;/a&gt;
&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%2F250ez3jjz60ck78f39aj.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%2F250ez3jjz60ck78f39aj.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Créditos da imagem acima: Livro C++ Concurrency in Action.&lt;/p&gt;

&lt;p&gt;A abordagem alternativa para a concorrência é executar vários threads em um único processo. Os threads são muito parecidos com processos leves: cada thread funciona independentemente dos outros, e cada um pode executar uma seqüência diferente de instruções. Mas todos os threads em um processo compartilham o mesmo espaço de endereço, e a maioria dos dados pode ser acessada diretamente de todos os threads - variáveis globais permanecem globais, e ponteiros ou referências a objetos ou dados podem ser passados entre os threads. Embora muitas vezes seja possível compartilhar memória entre processos, isto é complicado de configurar e muitas vezes difícil de gerenciar, porque os endereços de memória dos mesmos dados não são necessariamente os mesmos em processos diferentes. A Figura 1.4 mostra dois threads dentro de um processo comunicando através da memória compartilhada.&lt;/p&gt;

&lt;p&gt;O espaço de endereços compartilhado e a falta de proteção dos dados entre os threads fazem com que a sobrecarga (overhead) associada ao uso de múltiplos threads seja muito menor do que a do uso de múltiplos processos, porque o sistema operacional tem menos contabilidade (bookkeeping) a fazer. Mas a flexibilidade da memória compartilhada também vem com um preço: se os dados são acessados por múltiplos threads, o programador da aplicação deve garantir que a visualização dos dados vistos por cada thread seja consistente sempre que ela for acessada. As questões relacionadas ao compartilhamento de dados entre threads, e as ferramentas a serem usadas e as diretrizes a serem seguidas para evitar problemas são abordadas no livro &lt;strong&gt;C++ Concurrency in Action&lt;/strong&gt;. Os problemas não são intransponíveis, desde que se tome o cuidado adequado ao escrever o código, mas eles significam que muita reflexão deve ir para a comunicação entre os threads.&lt;/p&gt;

&lt;p&gt;A baixa sobrecarga associada ao lançamento e à comunicação entre múltiplos threads dentro de um processo em comparação com o lançamento e a comunicação entre múltiplos processos de uma única thread significa que esta é a abordagem favorecida para a concorrência nas linguagens orientadas a objetos, incluindo C++, apesar dos problemas potenciais decorrentes da memória compartilhada.&lt;/p&gt;




&lt;h1&gt;
  
  
  Conclusão &lt;a&gt;
&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;Se eu pudesse resumir concorrência em poucas palavras, eu diria que concorrencia é quando duas ou mais atividades independentes acontecem ao mesmo tempo quando não há uma ordem específica. Esse post foi realmente só uma introdução sobre o assunto. Há muito conhecimento ainda pra ser estudado quando falamos em concorrência com múltiplos threads ou concorrência com múltiplos processos. Cada abordagem tem seus pontos positivos e negativos e, dependendo da linguagem de programação que você atua; você terá que focar mais em umas dessas abordagens. O próximo passo agora é procurar colocar a mão no código visando esses conceitos e como isso pode melhorar e trazer benefícios ao seu software.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://go.hotmart.com/H93763859E" rel="noopener noreferrer"&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%2F72gnny6fjwnmku1x3rr4.png" alt="Formação TS"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>concurrency</category>
      <category>programming</category>
      <category>performance</category>
    </item>
    <item>
      <title>💧📆🏛️ Um guia para uma arquitetura orientada a eventos em Elixir</title>
      <dc:creator>Dev Maiqui 🇧🇷</dc:creator>
      <pubDate>Tue, 31 May 2022 11:33:58 +0000</pubDate>
      <link>https://forem.com/maiquitome/um-guia-para-uma-arquitetura-orientada-a-eventos-em-elixir-493d</link>
      <guid>https://forem.com/maiquitome/um-guia-para-uma-arquitetura-orientada-a-eventos-em-elixir-493d</guid>
      <description>&lt;p&gt;Esta é uma tradução do post &lt;a href="https://blog.appsignal.com/2022/05/10/a-guide-to-event-driven-architecture-in-elixir.html?utm_source=elixir-radar-sponsored&amp;amp;utm_medium=email&amp;amp;utm_campaign=2022-05-10" rel="noopener noreferrer"&gt;A Guide to Event-Driven Architecture in Elixir&lt;/a&gt; escrito por &lt;a href="https://blog.appsignal.com/authors/sapan-diwakar" rel="noopener noreferrer"&gt;Sapan Diwakar&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Também acrescentei algumas imagens para exemplificar melhor a explicação. Na dúvida sobre a tradução visite o post original. Vamos ao post.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://go.hotmart.com/R93865620U" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpkoqkmh9hic17tnddjf6.png" alt="A Jornada do Autodidata em Inglês" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Neste post, exploraremos como a &lt;strong&gt;arquitetura orientada a eventos (event-driven architecture)&lt;/strong&gt; pode tornar sua aplicação mais responsiva aos usuários e desacoplar seus módulos para uma melhor experiência do desenvolvedor.&lt;/p&gt;

&lt;p&gt;Também analisaremos vários métodos de implementação de arquitetura orientada a eventos com Elixir. A linguagem Elixir é particularmente boa para isso devido às APIs de passagem de mensagens avançadas e concisas que ela oferece e ao excelente suporte da BEAM para a concorrência.&lt;/p&gt;

&lt;p&gt;Mas primeiro: o que é exatamente uma arquitetura orientada a eventos?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Arquitetura orientada a eventos: Uma Introdução&lt;/li&gt;
&lt;li&gt;Construindo blocos de uma arquitetura orientada a eventos&lt;/li&gt;
&lt;li&gt;Benefícios da arquitetura orientada a eventos&lt;/li&gt;
&lt;li&gt;Abordagens

&lt;ul&gt;
&lt;li&gt;Arquitetura síncrona orientada a eventos em Elixir&lt;/li&gt;
&lt;li&gt;Usando o GenServer na arquitetura orientada a eventos em Elixir&lt;/li&gt;
&lt;li&gt;Implementação orientada a eventos usando GenStage em Elixir&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Conclusão: Arquitetura orientada a eventos em Elixir - Indo além do GenStage&lt;/li&gt;

&lt;/ul&gt;

&lt;h1&gt;
  
  
  Arquitetura orientada a eventos: Uma Introdução &lt;a&gt;
&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;A arquitetura orientada a eventos é uma &lt;strong&gt;arquitetura onde os eventos controlam o comportamento e o fluxo de sua aplicação&lt;/strong&gt;. Os principais componentes da arquitetura são os produtores de eventos &lt;code&gt;(event producers)&lt;/code&gt;, o barramento de eventos &lt;code&gt;(event bus)&lt;/code&gt; e os consumidores de eventos &lt;code&gt;(event consumers)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frzf1tbygi002oblpusq9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frzf1tbygi002oblpusq9.png" alt="Image description" width="800" height="481"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Um evento pode ser &lt;strong&gt;qualquer coisa que represente uma mudança de estado no sistema&lt;/strong&gt;. Por exemplo, em uma aplicação de comércio eletrônico ‘e-commerce’, a compra de um produto pelo usuário poderia produzir um &lt;strong&gt;evento de venda&lt;/strong&gt; ao qual o consumidor poderia então iniciar um processo de atualização de estoque.&lt;/p&gt;

&lt;p&gt;Uma arquitetura baseada em eventos permite que as aplicações atuem em eventos à medida que eles ocorrem. Diferentes partes de uma aplicação funcionam e se desenvolvem de forma relativamente independente em um projeto bem elaborado, baseado em eventos. As organizações podem designar equipes separadas para partes focadas da aplicação e racionalizar o fluxo de trabalho. Isto também cria uma fronteira clara entre diferentes partes de uma aplicação, auxiliando em futuros exercícios de escalabilidade.&lt;/p&gt;

&lt;p&gt;A arquitetura orientada por eventos ganhou popularidade principalmente com produtos baseados em microserviços, mas também pode ser usada para um monólito.&lt;/p&gt;

&lt;p&gt;As coisas são sempre mais claras com um exemplo, então vamos olhar para um.&lt;/p&gt;

&lt;h1&gt;
  
  
  Construindo blocos de uma arquitetura orientada a eventos &lt;a&gt;
&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;Vamos discutir cada bloco de construção em detalhes, usando uma aplicação de ‘e-commerce’ como exemplo.&lt;/p&gt;

&lt;p&gt;Imagine que um usuário faz uma nova compra em um ‘website’. O novo pedido é um evento gerado pela parte que controla o pedido: o &lt;strong&gt;event producer&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;O evento pode ser empurrado para um &lt;strong&gt;event bus&lt;/strong&gt;. O &lt;strong&gt;event bus&lt;/strong&gt; pode ser qualquer coisa, como, por exemplo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uma tabela no banco de dados.&lt;/li&gt;
&lt;li&gt;Uma fila de eventos em memória dentro da aplicação.&lt;/li&gt;
&lt;li&gt;Uma ferramenta externa como RabbitMQ ou Apache Kafka.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Os &lt;strong&gt;event producers&lt;/strong&gt; interessados neste tipo de evento podem se inscrever no &lt;strong&gt;event bus&lt;/strong&gt;. O evento é entregue-lhes, e eles fazem algum processamento em cima dele.&lt;/p&gt;

&lt;p&gt;Por exemplo, um sistema de gerenciamento de estoque assinaria (subscribe) o novo evento de pedido e atualizaria o estoque do produto. Outro sistema também poderia escolher o mesmo evento no pedido - por exemplo, um serviço de atendimento poderia processar esse evento e criar uma rota de entrega para o produto.&lt;/p&gt;

&lt;h1&gt;
  
  
  Benefícios da arquitetura orientada a eventos &lt;a&gt;
&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;Há várias vantagens em utilizar uma &lt;strong&gt;arquitetura orientada a eventos&lt;/strong&gt; ao invés de uma que &lt;strong&gt;processa tudo sequencialmente&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Uma arquitetura orientada a eventos nos permite construir &lt;strong&gt;várias partes independentes&lt;/strong&gt; de uma aplicação para trabalhar com o &lt;strong&gt;mesmo evento e realizar diferentes tarefas focadas&lt;/strong&gt;. Isto pode ser vantajoso por um par de razões:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uma equipe precisa se concentrar apenas em uma parte.&lt;/li&gt;
&lt;li&gt;O código de aplicação para partes pequenas pode ser simples.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Outra vantagem do conceito é que ele nos permite fornecer uma ‘interface’ rápida ao usuário. Como exemplo da aplicação acima, um usuário precisa fazer um pedido. A aplicação pode continuar processando todas as outras tarefas não-interativas, como atualizar seu inventário e interagir com a aplicação de entrega, sem a atenção do usuário.&lt;/p&gt;

&lt;p&gt;Isto também torna muito fácil acrescentar novas etapas de processamento no pipeline do evento. Por exemplo, digamos que precisamos de uma tarefa adicional a ser realizada a partir de um evento. Só precisamos adicionar um novo consumidor para lidar com o evento, sem tocar em nenhuma outra parte da aplicação.&lt;/p&gt;

&lt;p&gt;Finalmente, é muito mais fácil escalar cada módulo individual se ele for desacoplado dos outros, do que escalar uma aplicação inteira em conjunto. Isto é ainda mais benéfico ao ter uma parte que consome muito mais recursos do que suas contrapartes no pipeline de processamento de eventos.&lt;/p&gt;

&lt;p&gt;Mas a arquitetura orientada a eventos não vem sem desvantagens quando não é bem pensada. Se aplicada a problemas muito simples, ela pode levar a fluxos de trabalho complexos que são lentos e difíceis de depurar.&lt;/p&gt;

&lt;p&gt;Vamos explorar algumas maneiras simples de implementar uma arquitetura orientada a eventos com Elixir, sem a necessidade de escrever partes complexas de código.&lt;/p&gt;

&lt;h1&gt;
  
  
  Arquitetura síncrona orientada a eventos em Elixir &lt;a&gt;
&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;A maneira mais simples &lt;strong&gt;(e mais ineficiente)&lt;/strong&gt; de executar o fluxo acima seria &lt;strong&gt;fazer tudo de forma síncrona&lt;/strong&gt; no pedido do usuário.&lt;/p&gt;

&lt;p&gt;Portanto, se você tiver um módulo de &lt;strong&gt;Pedidos (Orders)&lt;/strong&gt; que processe o pedido de um usuário, a &lt;strong&gt;implementação síncrona&lt;/strong&gt; poderia se parecer com isto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;Orders&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;create_order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="c1"&gt;# salva o pedido&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;save_order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# atualiza o estoque&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_inventory&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;update_inventory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# cria a entrega&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_delivery&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_delivery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# retorna o pedido&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Podemos melhorar isto para que os consumidores de novos eventos possam escalar mais facilmente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;Orders&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="nv"&gt;@event_consumers&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;Inventory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:handle_event&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;Delivery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:handle_event&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;create_order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;save_order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Orders&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;type:&lt;/span&gt; &lt;span class="ss"&gt;:new_order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;payload:&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nv"&gt;@event_consumers&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com esta implementação, tudo o que precisamos fazer para adicionar novos consumidores é adicionar a especificação na lista &lt;code&gt;@event_consumers&lt;/code&gt;, e esses consumidores podem trabalhar independentemente.&lt;/p&gt;

&lt;p&gt;Embora a abordagem síncrona funcione bem para um pequeno número de consumidores, ela tem uma desvantagem. A criação de um pedido pode levar muito tempo porque será necessário esperar a atualização do estoque e a criação da entrega.&lt;/p&gt;

&lt;p&gt;Estas são tarefas internas que podem ser realizadas &lt;strong&gt;sem interação do usuário&lt;/strong&gt; e movidas da cadeia síncrona.&lt;/p&gt;

&lt;p&gt;Vamos ver como podemos racionalizar ainda mais a arquitetura orientada a eventos usando o &lt;a href="https://hexdocs.pm/elixir/1.13/GenServer.html" rel="noopener noreferrer"&gt;GenServer&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Usando o GenServer na arquitetura orientada a eventos em Elixir &lt;a&gt;
&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;Para esta implementação, executaremos um processo separado para cada consumidor. Estes se inscreverão num evento de um produtor e executarão suas tarefas simultaneamente.&lt;/p&gt;

&lt;p&gt;Para o &lt;strong&gt;event bus&lt;/strong&gt;, podemos utilizar o &lt;a href="https://hexdocs.pm/phoenix_pubsub/Phoenix.PubSub.html" rel="noopener noreferrer"&gt;Phoenix.PubSub&lt;/a&gt;. Note que é possível para aplicativos que não usam Phoenix &lt;a href="https://hexdocs.pm/elixir/Registry.html#module-using-as-a-pubsub" rel="noopener noreferrer"&gt;usar diretamente o Registro como um PubSub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff4dfjsl7ud4e210mlbem.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff4dfjsl7ud4e210mlbem.png" alt="Image description" width="395" height="139"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Primeiro, vamos olhar para o produtor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;Orders&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;create_order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;save_order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Orders&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;type:&lt;/span&gt; &lt;span class="ss"&gt;:new_order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;payload:&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="no"&gt;Phoenix&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;PubSub&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;broadcast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:my_app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"new_order"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em um novo pedido (order), criamos a estrutura do evento e usamos o &lt;code&gt;Phoenix.PubSub.broadcast/3&lt;/code&gt; para transmitir esse evento no barramento (bus). Como você pode ver, é muito mais simples do que a implementação anterior, onde o módulo de &lt;code&gt;Orders&lt;/code&gt; processava tarefas do outro módulo em série.&lt;/p&gt;

&lt;p&gt;Os consumidores podem então assinar (subscribe) o tópico &lt;code&gt;new_order&lt;/code&gt; e implementar o &lt;code&gt;handle_info/2&lt;/code&gt; para serem notificados toda vez que um novo evento é publicado pelo produtor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;Inventory&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;GenServer&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;GenServer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_opts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="no"&gt;Phoenix&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;PubSub&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:my_app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"new_order"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;handle_info&lt;/span&gt;&lt;span class="p"&gt;(%&lt;/span&gt;&lt;span class="no"&gt;Orders&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;type:&lt;/span&gt; &lt;span class="ss"&gt;:new_order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;payload:&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;consume&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:noreply&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O módulo de &lt;code&gt;Delivery&lt;/code&gt; será muito semelhante ao acima mencionado, por isso estou pulando aqui.&lt;/p&gt;

&lt;p&gt;Como você pode ver, isto é muito melhor do que as implementações anteriores. Os módulos de &lt;code&gt;Inventory&lt;/code&gt; e &lt;code&gt;Delivery&lt;/code&gt; podem se inscrever independentemente para o tópico &lt;code&gt;new_order&lt;/code&gt;.  O módulo &lt;code&gt;Orders&lt;/code&gt; transmite (broadcasts) para este tópico sobre novos pedidos e eventos são entregues para os processos inscritos.&lt;/p&gt;

&lt;p&gt;Você pode até distribuir isto entre vários nós e Phoenix.PubSub (com um PG, Redis ou outro adaptador), espalhando os eventos para todos os nós.&lt;/p&gt;

&lt;p&gt;Ótimo, certo? Na verdade, não. Há vários problemas com esta abordagem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;O PubSub fornece uma transmissão em tempo real sem fila de mensagens, portanto, se um dos processos do assinante estiver em suspenso, ele pode perder as transmissões.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Se o assinante fizer algum trabalho pesado, ele pode não conseguir acompanhar as mensagens recebidas, resultando em timeouts e, conseqüentemente, em um colapso da árvore de processos.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Se o assinante encontrar um erro no processamento de uma mensagem, ela é considerada consumida e não será novamente processada (retried) mais tarde.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Portanto, esta abordagem é uma má abordagem a ser seguida para nosso caso de uso atual.&lt;/p&gt;

&lt;p&gt;Entretanto, a abordagem ainda tem seus casos de uso. Ela pode ser usada para tarefas que não são críticas, ou que podem ser corrigidas com a próxima mensagem: por exemplo, se uma tarefa computar as sugestões para as próximas compras de um usuário com base em sua última compra. Embora isto também precise ser acionado em um novo pedido, não é exatamente crítico (para um site tradicional de e-commerce) e pode recalcular as sugestões para um usuário em sua próxima compra.&lt;/p&gt;

&lt;h1&gt;
  
  
  Implementação orientada a eventos usando GenStage em Elixir &lt;a&gt;
&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;Na seção anterior, vimos uma grande implementação de nosso sistema orientado a eventos utilizando o GenServer. Mas ele não veio sem suas limitações. Vamos ver como o &lt;a href="https://hexdocs.pm/gen_stage/GenStage.html" rel="noopener noreferrer"&gt;GenStage&lt;/a&gt; se comporta.&lt;/p&gt;

&lt;p&gt;O &lt;strong&gt;GenStage&lt;/strong&gt; faz uma distinção clara entre &lt;code&gt;producers&lt;/code&gt;, &lt;code&gt;consumers&lt;/code&gt; e &lt;code&gt;producer_consumers&lt;/code&gt;, e cada processo tem que escolher um quando começa (em seu &lt;code&gt;init/1&lt;/code&gt;). Em nosso caso, tanto o &lt;code&gt;Inventory&lt;/code&gt; quanto o &lt;code&gt;Delivery&lt;/code&gt; são &lt;code&gt;consumers&lt;/code&gt;, e &lt;code&gt;Orders&lt;/code&gt; é um &lt;code&gt;producer&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;É aqui que as coisas começam a ficar um pouco complicadas. O GenStage tem um conceito de demanda. Cada &lt;code&gt;consumer&lt;/code&gt; pode emitir uma demanda de quantos eventos ele pode lidar. O &lt;code&gt;producer&lt;/code&gt; precisa enviar esses eventos para o &lt;code&gt;consumer&lt;/code&gt;. Vamos ver um &lt;code&gt;producer&lt;/code&gt; básico em ação.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;Orders&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;GenStage&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="no"&gt;GenStage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_opts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:producer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:some_state_which_does_not_currently_mattere&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;create_order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="no"&gt;GenStage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:create_order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;handle_cast&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="ss"&gt;:create_order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;save_order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:noreply&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[%&lt;/span&gt;&lt;span class="no"&gt;Orders&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;type:&lt;/span&gt; &lt;span class="n"&gt;new_order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;payload:&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;handle_demand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_demand&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:noreply&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A carne de nosso código está em &lt;code&gt;handle_cast&lt;/code&gt;, onde guardamos o pedido (order) e devolvemos uma tupla como &lt;code&gt;{:noreply, events, new_state}&lt;/code&gt;. Os novos eventos são armazenados em um buffer &lt;strong&gt;GenStage&lt;/strong&gt; interno e enviados aos consumidores à medida que eles fazem novas demandas (ou imediatamente, se houver consumidores com demanda não atendida).&lt;/p&gt;

&lt;p&gt;Vamos checar uma amostra da implementação do &lt;code&gt;consumer&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;Inventory&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;GenStage&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="no"&gt;GenStage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_opts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:consumer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="ss"&gt;subscribe_to:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Orders&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;handle_events&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;handle_event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;&amp;amp;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;&amp;amp;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:noreply&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;handle_event&lt;/span&gt;&lt;span class="p"&gt;(%&lt;/span&gt;&lt;span class="no"&gt;Orders&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;type:&lt;/span&gt; &lt;span class="ss"&gt;:new_order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;payload:&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;new_state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;update_inventory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;new_state&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No &lt;code&gt;consumer&lt;/code&gt;, primeiro avisa de que temos um &lt;code&gt;subscribe_to&lt;/code&gt; (inscrição_para) dentro do &lt;code&gt;init/1&lt;/code&gt;. Isto automaticamente assina/inscreve (subscribe) o &lt;code&gt;Inventory&lt;/code&gt; para qualquer evento publicado por &lt;code&gt;Orders&lt;/code&gt;. Favor verificar a documentação &lt;a href="https://hexdocs.pm/gen_stage/GenStage.html#c:init/1" rel="noopener noreferrer"&gt;GenStage para opções adicionais disponíveis no init&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Aqui, a maior parte do trabalho acontece dentro do &lt;code&gt;handle_events/3&lt;/code&gt;, que é automaticamente chamado pela &lt;strong&gt;GenStage&lt;/strong&gt; assim que novos eventos se tornam disponíveis. Tratamos aqui do evento &lt;code&gt;new_order&lt;/code&gt;, atualizando o &lt;code&gt;inventory&lt;/code&gt; e retornando um novo estado.&lt;/p&gt;

&lt;p&gt;Com esta simples implementação, obtemos vários benefícios que superam a implementação do GenServer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Armazenamento automático de eventos dentro do buffer interno do GenStage quando o &lt;code&gt;producer&lt;/code&gt; tem novos eventos sem nenhum &lt;code&gt;consumer&lt;/code&gt; disponível.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mesmo que os &lt;code&gt;consumers&lt;/code&gt; estejam ausentes quando alguns eventos são produzidos, nós ainda temos a garantia de recebê-los quando o &lt;code&gt;consumer&lt;/code&gt; volta a ficar disponível.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hexdocs.pm/gen_stage/GenStage.html#module-buffering-demand" rel="noopener noreferrer"&gt;Confira o guia da Genstage sobre a demanda de buffering&lt;/a&gt; para uma lógica de buffering avançada.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Distribuição automática de trabalho em múltiplos consumidores.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Se você tem tarefas pesadas de consumo, você pode iniciar múltiplos processos de consumo. O &lt;a href="https://hexdocs.pm/gen_stage/GenStage.DemandDispatcher.html" rel="noopener noreferrer"&gt;DemandDispatcher&lt;/a&gt; padrão para GenStage distribuirá o trabalho uniformemente por todos os processos.&lt;/p&gt;

&lt;p&gt;Veja o &lt;a href="https://hexdocs.pm/gen_stage/GenStage.Dispatcher.html" rel="noopener noreferrer"&gt;GenStage.Dispatcher&lt;/a&gt; para outras estratégias de despacho para &lt;a href="https://hexdocs.pm/gen_stage/GenStage.BroadcastDispatcher.html" rel="noopener noreferrer"&gt;distribuir eventos a todos os consumidores&lt;/a&gt; ou &lt;a href="https://hexdocs.pm/gen_stage/GenStage.PartitionDispatcher.html" rel="noopener noreferrer"&gt;distribuição de partições aos consumidores com base em uma função hash&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Mas, como no &lt;strong&gt;GenServer&lt;/strong&gt; ou na &lt;strong&gt;implementação síncrona&lt;/strong&gt;, o uso do GenStage não vem sem seus problemas.&lt;/p&gt;

&lt;p&gt;Se um &lt;code&gt;consumer&lt;/code&gt; se chocar enquanto estiver processando um evento, o GenStage considerará o evento entregue e não o enviará novamente quando o &lt;code&gt;consumer&lt;/code&gt; voltar a ficar disponível.&lt;/p&gt;

&lt;p&gt;Para ter certeza de que você rastreia corretamente os acidentes, você pode usar um serviço de monitoramento como o &lt;a href="https://www.appsignal.com/" rel="noopener noreferrer"&gt;AppSignal&lt;/a&gt;. O AppSignal é [fácil de instalar para sua aplicação Elixir] e ajuda a monitorar o desempenho, assim como &lt;a href="https://www.appsignal.com/tour/errors" rel="noopener noreferrer"&gt;rastrear erros&lt;/a&gt;. Aqui está um exemplo de um painel de controle de erros que o AppSignal fornece:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fshksgj4uma7pqlyr58kl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fshksgj4uma7pqlyr58kl.png" alt="Image description" width="800" height="578"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Você também pode configurar notificações de colisões via AppSignal.&lt;/p&gt;

&lt;p&gt;No lado do aplicativo, você pode armazenar tais eventos em uma loja persistente uma vez que eles sejam entregues ao consumidor (consumer). Se o consumidor se chocar, então uma vez que se recupere, pode retornar aos eventos em cache.&lt;/p&gt;

&lt;p&gt;Seja muito cauteloso em produzir muitos eventos sem consumidores suficientes, no entanto. Enquanto a GenStage oferece um buffer automático de eventos, este buffer tem um tamanho máximo (configurável) e um tamanho máximo prático limitado pela memória do servidor.&lt;/p&gt;

&lt;p&gt;Se você não controla a freqüência com que os eventos são produzidos, considere o uso de um armazenamento de dados externo como Redis ou Postgres para fazer o buffer de eventos.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusão: Arquitetura orientada a eventos em Elixir - Indo além do GenStage &lt;a&gt;
&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;Neste post, examinamos três abordagens para implementar um sistema orientado a eventos no Elixir: de forma síncrona, usando o GenServer, e finalmente, usando o GenStage. Examinamos algumas das vantagens e desvantagens de cada abordagem.&lt;/p&gt;

&lt;p&gt;O exemplo simples do &lt;strong&gt;GenStage&lt;/strong&gt; pode ser um ponto de partida para a implementação de complexos pipelines de processamento de dados orientados por eventos que abrangem vários nós. Sugiro que você leia a grande &lt;a href="https://hexdocs.pm/gen_stage/GenStage.html" rel="noopener noreferrer"&gt;documentação do GenStage para obter mais informações&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Se você estiver procurando por uma abstração ainda maior, a &lt;a href="https://elixir-broadway.org/" rel="noopener noreferrer"&gt;Broadway&lt;/a&gt; é um bom ponto de partida. Ela é construída sobre o GenStage e oferece várias características adicionais, incluindo o consumo de dados de filas externas como Amazon SQS, Apache Kafka, e RabbitMQ.&lt;/p&gt;

&lt;p&gt;Até a próxima vez, boa codificação!&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>braziliandevs</category>
      <category>eventdriven</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
