<?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: Igor Oliveira</title>
    <description>The latest articles on Forem by Igor Oliveira (@devigor).</description>
    <link>https://forem.com/devigor</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%2F167647%2Fc1fbf029-2e99-4bc9-beed-ca7217362271.jpeg</url>
      <title>Forem: Igor Oliveira</title>
      <link>https://forem.com/devigor</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/devigor"/>
    <language>en</language>
    <item>
      <title>Criando uma plataforma do 0 - Dia 2</title>
      <dc:creator>Igor Oliveira</dc:creator>
      <pubDate>Sat, 04 Nov 2023 14:06:14 +0000</pubDate>
      <link>https://forem.com/devigor/criando-uma-plataforma-do-0-dia-1-4i8n</link>
      <guid>https://forem.com/devigor/criando-uma-plataforma-do-0-dia-1-4i8n</guid>
      <description>&lt;p&gt;Nesse segundo dia, eu fiz a parte de login e cadastro da aplicação e para facilitar a vida, fiz uso do &lt;a href="[Laravel%20Sanctum%20-%20Laravel%2010.x%20-%20The%20PHP%20Framework%20For%20Web%20Artisans](https://laravel.com/docs/10.x/sanctum)"&gt;Laravel Sanctun&lt;/a&gt;. O Laravel Sanctum já nos entrega um sistema de autenticação baseado em tokens para usar em nosso front end ou mobile. Dessa forma, cada usuário na nossa aplicação vai ter um token e o interessante é que esse token pode receber o que a documentação chama de escopo e habilidades. Onde podemos definir o que aquele tipo de token pode fazer e no seu escopo podemos definir a expiração token também.&lt;br&gt;
Definido que iria usar o Sanctum, eu segui a documentação no site do próprio Laravel para fazer a instalação dele, mas a única que precisei fazer de fato que o Laravel não me entregou pronto, foi descomentar a linha &lt;code&gt;\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class&lt;/code&gt; que se estava no arquivo &lt;code&gt;Kernel.php&lt;/code&gt;, para ter a certeza que as request que irão vir do nosso FrontEnd irão ser Stateful, isto vai dizer para nosso BackEnd manter o estado da nossa sessão.&lt;br&gt;
Outra alteração que precisei fazer foi no arquivo de migration de o Laravel Sanctum gera para gente, no primeiro dia foi definido que a Chave Primária (PK) da nossa tabela de usuários seria um UUID e quando comecei a testar me deparei com um erro dizendo que uma coluna que a migration criou e iria guardar o ID do usuário não aceitava valor do tipo UUID, então a migration que era dessa forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Schema&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'personal_access_tokens'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Blueprint&lt;/span&gt; &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;morphs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'tokenable'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'token'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;unique&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'abilities'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;nullable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'last_used_at'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;nullable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'expires_at'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;nullable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;timestamps&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;Ficou dessa forma, a mudança ocorre na coluna &lt;code&gt;tokenable&lt;/code&gt;, passamos a utilizar &lt;code&gt;uuidMorphs&lt;/code&gt; para informar que a coluna irá aceitar tipos UUID:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Schema&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'personal_access_tokens'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Blueprint&lt;/span&gt; &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;uuidMorphs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'tokenable'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'token'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;unique&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'abilities'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;nullable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'last_used_at'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;nullable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'expires_at'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;nullable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;timestamps&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;Feito essa mudança, partiu agora criar nosso Controller para lidar com o Login e Cadastro dos usuários. Para isso é fácil, bastou rodar o comando &lt;code&gt;php artisan make:controller Api/Auth/AuthController&lt;/code&gt;, esse comando irá criar um Controller dentro da pasta &lt;code&gt;app/Http/Controllers/Api/Auth/AuthController.php&lt;/code&gt;.&lt;br&gt;
Agora começa a parte boa, codar a lógica de primeiro de login do usuário e isso foi bem simples, primeiro eu faço a validação dos campos que quero receber, no login eu espero receber o e-mail e senha do usuário, esses dados vão ser do tipo string e obrigatórios, depois eu procuro se tem algum usuário com esse e-mail no banco de dados e faço a verificação se a senha está correta, feita essa primeira parte e tudo estiver ok, eu crio o token daquele usuário e retorno o usuário e o token como resposta.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;Response&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="s1"&gt;'email'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'required|string'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="s1"&gt;'password'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'required|string'&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nc"&gt;Hash&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'password'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="s1"&gt;'message'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Email ou senha incorretos'&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nv"&gt;$token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;createToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'apiToken'&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;plainTextToken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="s1"&gt;'user'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="s1"&gt;'token'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$token&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;200&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;Lógica de login feita, basta só cadastrar a rota no arquivo &lt;code&gt;routes/api.php&lt;/code&gt; e o login já está pronto.&lt;br&gt;
Para cadastro a lógica é parecida, a diferença é que eu faço a validação também do primeiro e último nome e faço um regex na senha para ver se ela atende uma determinada condição e também já gero o token, porque o objetivo é assim que ele fizer o cadastro já cai dentro da plataforma para começar a usar.&lt;/p&gt;

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

&lt;p&gt;Bom, nesse segundo dia foi isso, pretendo ainda melhor essa parte da geração do token, pois ele por padrão nunca expira e isso no objetivo que tenho em mente pode não ser bom, então as próximas partes eu irei colocar um tempo de expiração e também criar a rota para fazer o logout do usuário e apagar esse token no nosso banco de dados. Então é isso, devagar o sistema vai tomando forma e eu vou aprendendo cada vez mais!&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>fullstack</category>
      <category>product</category>
      <category>programming</category>
    </item>
    <item>
      <title>Criando uma plataforma do 0 - Dia 1</title>
      <dc:creator>Igor Oliveira</dc:creator>
      <pubDate>Sat, 04 Nov 2023 14:03:44 +0000</pubDate>
      <link>https://forem.com/devigor/criando-uma-plataforma-do-0-dia-1-91l</link>
      <guid>https://forem.com/devigor/criando-uma-plataforma-do-0-dia-1-91l</guid>
      <description>&lt;p&gt;Aqui vou documentar todo o processo de criação de um sistema de ponta a ponta, desde o levantamento inicial, passando pela escolha de tecnologias, desenvolvimento do BackEnd, FrontEnd e deploy da aplicação.&lt;/p&gt;

&lt;p&gt;Nesse primeiro dia, eu criei um mapa mental do objetivo e o fluxo básico da aplicação, descrevendo as tecnologias que vão ser usadas durante o desenvolvimento. Abaixo tem uma imagem desse mapa&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RDVUB1OY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dl4unl56vanxtb59hjq2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RDVUB1OY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dl4unl56vanxtb59hjq2.png" alt="Mapa" width="800" height="294"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O objetivo é simples, eu quero um lugar onde eu possa colocar o código de uma ação que comprei, a quantidade, o valor pago por cada ação e que caso queira fazer o upload da nota de corretagem, também seja possível. De começo é para ser algo simples e com o passar do tempo e conforme eu for estudando novas coisas, quero ir melhorando esse produto.&lt;/p&gt;

&lt;p&gt;A escolha de tecnologias foi com base em gosto, eu gosto muito de PHP e principalmente do Laravel, banco de dados o escolhido foi PostgreSQL, pois queria tentar algo novo já que estou acostumado a usar MySQL como banco de dados e a AWS vai ser para usar o S3 para guardar as notas de corretagem. O FrontEnd ainda não decidi se vou usar algo novo ou algo que já estou acostumado como um NextJS da vida, mas isso vai ser decisão para ser tomada mais para frente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dia 1 - parte 2
&lt;/h2&gt;

&lt;p&gt;Aproveitando o embalo, dei o start no projeto, comecei criando um projeto Laravel na minha máquina, usei o próprio &lt;a href="[Installation%20-%20Laravel%2010.x%20-%20The%20PHP%20Framework%20For%20Web%20Artisans](https://laravel.com/docs/10.x/installation#your-first-laravel-project)"&gt;exemplo&lt;/a&gt; do site para gerar o projeto. Também entrei no &lt;a href="[Docker%20Hub](https://hub.docker.com/_/postgres/)"&gt;Hub do Docker&lt;/a&gt; para poder criar um container com o banco de dados Postgres.&lt;br&gt;
Com o projeto gerado e o banco de dados de pé, eu fiz os seguintes passos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Primeiro fui no meu arquivo &lt;code&gt;.env&lt;/code&gt; e mudei as configurações para acessar o banco de dados. Coloquei o driver do Postgres que é o &lt;code&gt;pgsql&lt;/code&gt;, mudei a porta já que o Postgres usa a 5432 e mudei o usuário e senha para os valores que coloquei quando levantei o container&lt;/li&gt;
&lt;li&gt;Depois no arquivo de migrate que o próprio Laravel gera para o modelo de &lt;code&gt;User&lt;/code&gt; (que ele também já gera sozinho) eu fiz umas mudanças, primeiro eu mudei para a coluna ser um UUID e ser a chave primária da tabela, também acrescentei os campos &lt;code&gt;first_name&lt;/code&gt; e &lt;code&gt;last_name&lt;/code&gt;, retirei a verificação obrigatória de e-mail e o campo &lt;code&gt;remember_token&lt;/code&gt;. Com isso já estava na forma como planejei inicialmente, aí foi só rodar o comando &lt;code&gt;php artisan migrate&lt;/code&gt; e pronto, já tenho minha tabela pronta.&lt;/li&gt;
&lt;li&gt;Precisei fazer umas alterações no meu Model User, a primeira coisa foi colocar uma Trait &lt;code&gt;HasUuid&lt;/code&gt; para falar para o nosso modelo que vamos usar UUIDs, também adicionei os campos novos dentro do array &lt;code&gt;$fillable&lt;/code&gt; e removi os campos que eu não vou utilizar.&lt;/li&gt;
&lt;li&gt;E para finalizar o Laravel fornece uma Factory já pronta para o nosso usuário, só precisei remover alguns campos que eu não irei utilizar e adicionar os novos e depois disso no meu arquivo DatabaseSeeder, eu fiz o uso do nosso modelo para gerar usuários automaticamente e rodei um &lt;code&gt;php artisan db:seed&lt;/code&gt; para persistir os novos usuários no banco de dados.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Acho que para um primeiro dia está bom, a próxima parte vai ser fazer o CRUD de usuários e estou animado para continuar com o projeto!&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>fullstack</category>
      <category>programming</category>
      <category>product</category>
    </item>
    <item>
      <title>Um Estudo Sobre Generics no TypeScript</title>
      <dc:creator>Igor Oliveira</dc:creator>
      <pubDate>Thu, 07 Jul 2022 18:37:13 +0000</pubDate>
      <link>https://forem.com/devigor/um-estudo-sobre-generics-no-typescript-3doi</link>
      <guid>https://forem.com/devigor/um-estudo-sobre-generics-no-typescript-3doi</guid>
      <description>&lt;h2&gt;
  
  
  Um Estudo Sobre Generics no TypeScript
&lt;/h2&gt;

&lt;p&gt;Um assunto que confunde muita gente no começo da caminhada com TypeScript, são os Generics.&lt;/p&gt;

&lt;p&gt;Primeiro, vamos ver o que a documentação do TypeScript fala sobre os Generics:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“In languages like C# and Java, one of the main tools in the toolbox for creating reusable components is generics, that is, being able to create a component that can work over a variety of types rather than a single one. This allows users to consume these components and use their own types”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;O trecho que mais interessa é: &lt;em&gt;that is, being able to create a component that can work over a variety of types rather than a single one&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Em uma tradução livre quer dizer que Generics são capazes de criar componentes que funcionam de várias formas ao invés de apenas uma, ou seja, podemos dizer que os &lt;strong&gt;Generics são para os tipos o que valores são para os argumentos de uma função&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A syntax de um Generic
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3saa3Djj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ljj4kk6lga0ut5cicr9n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3saa3Djj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ljj4kk6lga0ut5cicr9n.png" alt="Componente inicial" width="800" height="237"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Os Generics sempre são envoltos de &lt;code&gt;**&amp;lt;&amp;gt;&lt;/code&gt;** e podem conter mais de uma Generic, veja os exemplos abaixo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aGOyZdY0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ad82yqf7zs9tm09f3j0c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aGOyZdY0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ad82yqf7zs9tm09f3j0c.png" alt="Múltiplas generics" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Geralmente, você verá as Generics sendo representadas por letras, isso foi uma convenção da comunidade. São elas:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;T - para tipos (types)&lt;/li&gt;
&lt;li&gt;S - para estados (state)&lt;/li&gt;
&lt;li&gt;K - para chaves (key)&lt;/li&gt;
&lt;li&gt;V - para valores (value)&lt;/li&gt;
&lt;li&gt;E - para elementos (element)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Bom, se o intuito da Generic é ajudar na construção de componentes que podem ser reutilizados, vamos criar um componente que vai ser um wrapper do axios, para nos ajduar nas chamadas para APIs&lt;/p&gt;

&lt;h2&gt;
  
  
  Criando o componente
&lt;/h2&gt;

&lt;p&gt;Nosso componente vai ser um cliente que recebe a url de uma API e faz um GET retornando um array, coisa simples, porém vai ser bem preciso para explicar como as Generics funcionam. Primeiro eu escrevi ele de uma forma engessada e aos poucos vamos refatorando ele&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SxqIYA_q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pmah7zbejgri36dt5ja0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SxqIYA_q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pmah7zbejgri36dt5ja0.png" alt="Inicio do componete" width="800" height="554"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Primeiro vamos relatar alguns pontos que podem ser melhorados e ir ponto a ponto melhorando nosso componente.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Primeiro, a URL da nossa API está fixa no código e isso não é legal, já que eu quero um componente que possa ser utilizado de diversas formas e com diferentes APIs, eu teria que receber como argumento na função. Nosso código agora vai ficar assim: &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YoQeS_Sm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ogii36txuflrdwyvr8wk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YoQeS_Sm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ogii36txuflrdwyvr8wk.png" alt="Modularizando o componente" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Segundo ponto, estamos usando TypeScript, porém nosso retorno não está tipado. Se fizermos &lt;code&gt;response.data[0].&lt;/code&gt; não teremos a inteligência do nosso editor para nos ajudar com o autocomplete e como fazemos a tipagem? Aqui vamos começar a ver os Generics sendo usados, o Axios permite o uso de Generics para que possamos tipar o retorno da nossa chamada e para isso basta passarmos nossa tipagem para &lt;code&gt;axios.get&amp;lt;Type&amp;gt;()&lt;/code&gt;. Nosso código agora fica assim:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qYxJyIZp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5p3rfgulvzcbdzhuqvna.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qYxJyIZp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5p3rfgulvzcbdzhuqvna.png" alt="Modularizando o componente" width="800" height="726"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Nosso código já está bem tipado, falamos que o retorno da nossa chamada vai ser um array do tipo Props e assim está bem legal nosso código já. Mas temos um problema, o que acontece se eu passar uma outra URL? O tipo que criamos só serve para um tipo de retorno e é ai que vamos entrar no uso das Generics, vamos deixar nosso código pronto para o uso das Generics:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--odfpFf0J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z7pnc1nma442eukl985w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--odfpFf0J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z7pnc1nma442eukl985w.png" alt="Componente final" width="800" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vou tentar explicar o que fiz nesse ponto 3, lembrando que lá em cima em disse que algumas letras a comunidade usa para representar as Generics, aqui eu passei &lt;code&gt;&amp;lt;T&amp;gt;&lt;/code&gt; para indicar que vamos repassar um tipo para a nossa função e depois para o axios. No código abaixo vamos ver como usamos nosso Client.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lwm1XSSU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pjgkn0cly42e6jijo7ch.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lwm1XSSU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pjgkn0cly42e6jijo7ch.png" alt="Usando o componente" width="800" height="485"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Por debaixo dos panos
&lt;/h2&gt;

&lt;p&gt;Para resumir o que o Generics faz por debaixo dos panos, é como se a gente tivesse uma função que recebe alguns parâmetros e essa função faz algo com esses parâmetros, no caso ele vai pegar o &lt;code&gt;&amp;lt;Props[]&amp;gt;&lt;/code&gt; e vai colocar onde está &lt;code&gt;&amp;lt;T&amp;gt;&lt;/code&gt; fazendo com os tipos sejam o que passamos no Generic de quando instanciamos nosso client. Abaixo vou deixar um GIF que me ajudou a elucidar o funcionamento das Generics&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uonspC5i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://miro.medium.com/proxy/1%2AZz4Y9ScEbGbRrtIWby4msg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uonspC5i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://miro.medium.com/proxy/1%2AZz4Y9ScEbGbRrtIWby4msg.gif" alt="https://miro.medium.com/proxy/1*Zz4Y9ScEbGbRrtIWby4msg.gif" width="780" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Um muito obrigado!
&lt;/h2&gt;

&lt;p&gt;A todos que leram até, meus mais sinceros agradecimentos! Espero que tenha gostado, sinta-se livre para me acompnhar nas minhas redes&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/ig0r_oliveiraa"&gt;Twitter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/devigor"&gt;Dev.to&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/oigorjs"&gt;Linkedin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/devigor"&gt;Github&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.typescriptlang.org/docs/handbook/2/generics.html"&gt;https://www.typescriptlang.org/docs/handbook/2/generics.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://oieduardorabelo.medium.com/typescript-entendendo-generics-por-completo-40a372aeea5"&gt;https://oieduardorabelo.medium.com/typescript-entendendo-generics-por-completo-40a372aeea5&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=eXVlK2PzE1k&amp;amp;ab_channel=Ot%C3%A1vioMiranda"&gt;https://www.youtube.com/watch?v=eXVlK2PzE1k&amp;amp;ab_channel=OtávioMiranda&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>typescript</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>generics</category>
    </item>
    <item>
      <title>Ententendo o useEffect</title>
      <dc:creator>Igor Oliveira</dc:creator>
      <pubDate>Wed, 29 Jun 2022 20:59:05 +0000</pubDate>
      <link>https://forem.com/devigor/ententendo-o-useeffect-5gg4</link>
      <guid>https://forem.com/devigor/ententendo-o-useeffect-5gg4</guid>
      <description>&lt;h2&gt;
  
  
  Entendendo o useEffect
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Esse artigo tem como intuito, esclarecer o uso do Hook useEffect que foi introduzido no React 16.8. Este hook foi um dos quais tive mais dificuldades para entender e resolvi compilar o que aprendi nesse artigo&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Primeiro, senta que lá vem teoria…
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--diYpab7f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://c.tenor.com/t4XpGIkuCK8AAAAC/senta-que.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--diYpab7f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://c.tenor.com/t4XpGIkuCK8AAAAC/senta-que.gif" alt="Senta, que lá vem história" width="320" height="240"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Antes de entramos no useEffect, vamos entender como funciona o ciclo de vida (lifecycle) de um componente. &lt;/p&gt;

&lt;p&gt;No React temos basicamente três fases principais de ciclo de vida de um componente, são eles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mounting -&lt;/strong&gt; é quando o elemento é colocado na DOM do navegador, ou seja, quando o elemento é renderizado em tela.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Updating -&lt;/strong&gt; é quando um elemento tem alguma prop ou estado atualizado, isso faz com que o componente seja renderizado novamente em tela.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unmounting -&lt;/strong&gt; essa é a última parte do lifecycle de um componente, é nesse momento em que o elemento é retirado da DOM ou como é mais comum falar, o elemento é desmontado e deixa de existir em tela.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dentro de cada fase de um lifecycle, o React antes da 16.8 possuia funções que ajudavam a manipular o elemento. Por exemplo, na fase de &lt;strong&gt;MOUNTING&lt;/strong&gt; tinha o &lt;code&gt;componentDidMount()&lt;/code&gt; que era chamado assim que o elemento entrava em tela, tinha o &lt;code&gt;getDerivedStateFromProps()&lt;/code&gt; que era executado antes do elemento entrar em tela. Na fase de &lt;strong&gt;UPDATING&lt;/strong&gt; havia o &lt;code&gt;shouldComponentUpdate()&lt;/code&gt; que retornava &lt;code&gt;true&lt;/code&gt; ou &lt;code&gt;false&lt;/code&gt; (por padrão é sempre true) e especificava se o React deveria prosseguir com a atualização ou não e o &lt;code&gt;componentDidUpdate()&lt;/code&gt; que executava algo assim que o componente atualizasse. Para finalizar, na parte de &lt;strong&gt;UNMOUNTING&lt;/strong&gt; tinhamos o &lt;code&gt;componentWillUnmount()&lt;/code&gt; que assim que o elemento saia da DOM ele era executado.&lt;/p&gt;

&lt;p&gt;Olha quantas funções internas temos para lidar com o &lt;em&gt;lifecycle&lt;/em&gt; dentro do React e isso foram apenas algumas funções, as que eram mais usadas no dia a dia do desenvolvedor. Em casos específicos era necessárias outras funções menos utilizadas.&lt;/p&gt;

&lt;h2&gt;
  
  
  A chegada dos Hooks
&lt;/h2&gt;

&lt;p&gt;Com a chegada do React 16.8, fomos introduzidos ao Hooks e que coisa maravilhosa foi. Com eles foi removida uma camada de complexidade que o React possuia, para podemos comparar, abaixo tem um contador escrito com o conceito de Classes e outro com Hooks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2GHcgxxM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c6q9v8nx894c0fxryryd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2GHcgxxM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c6q9v8nx894c0fxryryd.png" alt="Componente de classe" width="800" height="1189"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--s8rc89cp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lff1fz2z6egzrsfy7yb0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--s8rc89cp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lff1fz2z6egzrsfy7yb0.png" alt="Componente com hook" width="800" height="833"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Olha a diferença de escrita de um componente com Classe para um escrito com Hook, temos um código muito menor e mais legível. Esse exemplo é de manipulação de estado com o useState. Mas a pergunta é: onde entra o useEffect?&lt;/p&gt;

&lt;h2&gt;
  
  
  Utilizando o useEffect
&lt;/h2&gt;

&lt;p&gt;No começo desse artigo eu falei sobre como antes da versão do 16.8 era feito o &lt;em&gt;lifecycle,&lt;/em&gt; mas e agora como é feito? É bem simples, vamos começar analisando a sintaxe do useEffect.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xv-_14jA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5lu4etptp0z8fgxr3ucs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xv-_14jA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5lu4etptp0z8fgxr3ucs.png" alt="Sintaxe useEffect" width="434" height="166"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Podemos ver que o useEffect recebe uma função de callback e no final um array. A primeira coisa que me causou estranheza foi esse array no final, &lt;strong&gt;o que ele quer dizer?&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Nós chamamos ele de &lt;em&gt;array de dependências.&lt;/em&gt; No useEffect esse array pode não existir, pode existir e estar vazio e pode exister e conter um estado ou propriedade. Vamos entender melhor os casos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;useEffect sem o array de dependências -&lt;/strong&gt; nesse caso o nosso useEffect vai ser chamado em cada ação que o usuário fizer em nossa aplicação, isso pode causar alguns loops indesejados na nossa aplicação.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Com o array de dependências vazio -&lt;/strong&gt; com o array vazio, temos um comportamento semelhante ao &lt;code&gt;componentDidMount()&lt;/code&gt; que falamos anteriormente. Nesse caso, assim que nosso elemento entrar em tela o useEffect vai ser chamado.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Com o array de dependências possuindo uma prop ou estado -&lt;/strong&gt; podemos adicionar no array, uma propriedade que nosso componente recebe ou um estado interno e com isso, quando algum desses dados for atualizados nosso useEffect vai ser chamado.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Eu vou mostrar alguns exemplos de uso do useEffect:&lt;/p&gt;

&lt;h3&gt;
  
  
  Sem o array de dependências
&lt;/h3&gt;

&lt;p&gt;Nesse exemplo, a cada ação do usuário na tela o useEffect irá lançar um &lt;code&gt;console.log&lt;/code&gt; com a quantidade de vezes que o &lt;code&gt;count&lt;/code&gt; foi chamado.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--31ECjss3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x9glwo54xflu5o5vngmr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--31ECjss3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x9glwo54xflu5o5vngmr.png" alt="Sem o array de dependências" width="800" height="791"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Com o array de dependências vazio
&lt;/h3&gt;

&lt;p&gt;Melhorando ainda mais nosso exemplo, dessa vez vamos fazer uma chamada a API dentro do useEffect assim que nosso componente for montando em tela. Com isso teremos alguns dados em tela e como o array está vazio, o useEffect será chamado apenas uma vez.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_NAConf_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/awa8ooaqi3q7662qebkj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_NAConf_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/awa8ooaqi3q7662qebkj.png" alt="Com o array de dependências vazio" width="800" height="708"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Com o array de dependência contendo um estado
&lt;/h3&gt;

&lt;p&gt;Melhorando o exemplos que criamos no exemplo anterior, vamos colocar um botão que incrementa um contador e toda vez que o contador mudar será feita uma nova requisição e o retorno será o usuário com o ID referente ao valor do contador&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nQzYhVOH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rd8o6203w2oawe9cevbn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nQzYhVOH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rd8o6203w2oawe9cevbn.png" alt="Com o array de dependência contendo um estado" width="800" height="729"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Limpando a bagunça
&lt;/h2&gt;

&lt;p&gt;É comum quando um componente saia de tela, nós precisarmos limpar as coisas que foram feitas por ele. Antes da versão 16.6 do React nós utilizamos o &lt;code&gt;componentWillUnmount()&lt;/code&gt;. Porém agora com o useEffect ficou muito mais simples, basta no final retornamos uma função e assim que o componente sair de tela a função será chamada. Vamos ao exemplo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MVKja2yL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/leoexs5sulazwrnbf54w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MVKja2yL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/leoexs5sulazwrnbf54w.png" alt="Função de cleanup" width="788" height="564"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;É comum algumas funções do próprio JavaScript precisarem ser limpadas após alguma ação e quando isso for necessário o próprio React irá nos avisar, como por exemplo quando usamos a função &lt;code&gt;addEventListener()&lt;/code&gt; ****, depois dela ser executada é necessário fazermos a limpeza do evento com o &lt;code&gt;removeEventListener()&lt;/code&gt;. Antes do hooks a função a ser usada seria a &lt;code&gt;componentWillUnmount()&lt;/code&gt; e agora com os hooks basta retornarmos uma função no final do nosso useEffect que resolvemos esse problema.&lt;/p&gt;

&lt;h2&gt;
  
  
  Um muito obrigado!
&lt;/h2&gt;

&lt;p&gt;A todos que leram até, meus mais sinceros agradecimentos! Espero que tenha gostado, sinta-se livre para me acompnhar nas minhas redes&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/ig0r_oliveiraa"&gt;Twitter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/devigor"&gt;Dev.to&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/oigorjs"&gt;Linkedin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/devigor"&gt;Github&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.w3schools.com/react/react_lifecycle.asp"&gt;https://www.w3schools.com/react/react_lifecycle.asp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://overreacted.io/a-complete-guide-to-useeffect/"&gt;https://overreacted.io/a-complete-guide-to-useeffect&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pt-br.reactjs.org/docs/hooks-effect.html"&gt;https://pt-br.reactjs.org/docs/hooks-effect.html&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>hook</category>
      <category>useeffect</category>
    </item>
    <item>
      <title>ASDF: O gerenciador de versões universal!</title>
      <dc:creator>Igor Oliveira</dc:creator>
      <pubDate>Wed, 12 Jan 2022 16:51:34 +0000</pubDate>
      <link>https://forem.com/devigor/asdf-o-gerenciador-de-versoes-universal-47op</link>
      <guid>https://forem.com/devigor/asdf-o-gerenciador-de-versoes-universal-47op</guid>
      <description>&lt;p&gt;Hoje em dia em bem comun cada linguagem de programação ter seu próprio gerenciador de versão, como por exemplo o Node tem o NVM e o Ruby tem o RVM. Mas agora imagine que para cada linguagem que você use, você tenha que ter um gerenciador de versões diferentes e imagine o pior, e se tal linguagem não tiver um gerenciado de versões? Para isso foi criado o ASDF, ele permite que através de um único programa de CLI nós possamos instalar e gerenciar múltiplas versões de diferente linguagens.&lt;/p&gt;

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

&lt;p&gt;Vamos começar com o processo de instalação do ASDF, isso é bem simples. Basta entrar no seu terminal e digitar os seguintes comandos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/asdf-vm/asdf.git ~/.asdf &lt;span class="nt"&gt;--branch&lt;/span&gt; v0.9.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hoje o programa se encontra na versão 0.9.0 e ela que estamos instalando.&lt;/p&gt;

&lt;p&gt;Logo em seguida vamos configurar o ASDF no arquivo de configuração do nosso terminal, podendo ser tanto o arquivo &lt;code&gt;.bashrc&lt;/code&gt; ou &lt;code&gt;.zshrc&lt;/code&gt;. No meu caso eu estou utilizando o ZSH, logo vou fazer a configuração no &lt;code&gt;.zshrc&lt;/code&gt;. Para isso basta utilizar o seguinte comando no 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="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;". &lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.asdf/asdf.sh"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.zshrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Instalando e Gerenciando versões
&lt;/h2&gt;

&lt;p&gt;Primeiro de tudo, no ASDF cada linguagem de programação é um plugin. Vou deixar &lt;a href="https://github.com/asdf-vm/asdf-plugins"&gt;AQUI&lt;/a&gt; uma lista com todos os plugins disponíveis.&lt;br&gt;
Como exemplo para este artigo, vamos instalar o NodeJs utilizando o ASDF.&lt;br&gt;
Primeiro de tudo, precisamos entrar na &lt;a href="https://github.com/asdf-vm/asdf-nodejs"&gt;página do plugin&lt;/a&gt;. Nela vai conter todos os passos para a instalação. Mas no geral os passos são esse:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1° - Adicionar o plugin com &lt;code&gt;asdf plugin add &amp;lt;NOME&amp;gt; &amp;lt;LINK DO REPO&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;2° - Instalar o plugin com &lt;code&gt;asdf install &amp;lt;NOME&amp;gt; &amp;lt;VERSÃO&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vamos instalar o NodeJs para exemplificar melhor.&lt;/p&gt;

&lt;p&gt;Primeiro vamos adicionar o plugin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  asdf plugin add nodejs https://github.com/asdf-vm/asdf-nodejs.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora vamos instalar o plugin, para fazer a instalação da última versão de alguma linguagem, basta utilizar a tag latest. E para versões específicas basta utilizar o número da versão. Ex: 15.8.2&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    asdf &lt;span class="nb"&gt;install &lt;/span&gt;nodejs latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pronto, temos a última versão no Node instalada na nossa máquina!&lt;/p&gt;

&lt;h2&gt;
  
  
  Outros Comandos
&lt;/h2&gt;

&lt;p&gt;Vou deixar uma lista alguns comandos mais utilizados&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;asdf plugin add   // Adicionar um Plugin&lt;/li&gt;
&lt;li&gt;asdf install   // Instalar uma linguagem&lt;/li&gt;
&lt;li&gt;asdf plugin list all // Listar plugins instalados&lt;/li&gt;
&lt;li&gt;asdf remove  // Remover uma linguagem&lt;/li&gt;
&lt;li&gt;asdf update  // Atualizar uma linguagem&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>asdf</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
