<?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: Lucas Lomeu</title>
    <description>The latest articles on Forem by Lucas Lomeu (@lucaslomeu).</description>
    <link>https://forem.com/lucaslomeu</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%2F641676%2Fa508a851-cde1-48f9-95d6-b120bbca5324.png</url>
      <title>Forem: Lucas Lomeu</title>
      <link>https://forem.com/lucaslomeu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/lucaslomeu"/>
    <language>en</language>
    <item>
      <title>Building a Scalable URL Shortener</title>
      <dc:creator>Lucas Lomeu</dc:creator>
      <pubDate>Tue, 10 Feb 2026 11:08:45 +0000</pubDate>
      <link>https://forem.com/lucaslomeu/building-a-scalable-url-shortener-33ma</link>
      <guid>https://forem.com/lucaslomeu/building-a-scalable-url-shortener-33ma</guid>
      <description>&lt;p&gt;I thought a URL shortener was literally a simple CRUD. It turned out to be the exact opposite, so here’s how I designed and built mine.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Let's understand what we're building:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Convert &lt;code&gt;https://website.com/very/long/url&lt;/code&gt; into &lt;code&gt;short.com/aB3x&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Redirect users from short URL back to the original&lt;/li&gt;
&lt;li&gt;Handle 1,000+ writes/sec and 10,000+ reads/sec&lt;/li&gt;
&lt;li&gt;Never generate duplicate short codes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What makes it hard:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;IDs must be globally unique - no collisions&lt;/li&gt;
&lt;li&gt;Read-heavy workload - 10:1 read/write ratio&lt;/li&gt;
&lt;li&gt;Must scale horizontally&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Math Behind It
&lt;/h2&gt;

&lt;p&gt;Let's do some napkin math to understand scale:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;100 million URLs/day x (24 hours / 3600 ms) = &lt;strong&gt;~1,160 writes/sec&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;10:1 read ratio - 1,160 writes/sec x 10 = &lt;strong&gt;~11,600 reads/sec&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Over 10 years - 100M x 365 days * 10 years = &lt;strong&gt;~365 billion URLs&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Architecture: Hexagonal Pattern
&lt;/h2&gt;

&lt;p&gt;I chose &lt;strong&gt;Hexagonal Architecture&lt;/strong&gt; because it keeps the business logic independent from infrastructure. This makes it easier to swap databases, frameworks, or transport layers without touching the core of the application. It also aligns with what I’ve been studying lately, since I plan to dive deeper into this architecture and eventually write an article about it. &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%2Fn6t4yxaqockohmgd6330.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%2Fn6t4yxaqockohmgd6330.png" alt="Hexagonal Architecture" width="800" height="393"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Database Choice: PostgreSQL
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Strong consistency&lt;/strong&gt; – Ensures there are no duplicate short codes, even during network partitions&lt;br&gt;
&lt;strong&gt;ACID transactions&lt;/strong&gt; – ID generation and insertion happen atomically&lt;br&gt;
&lt;strong&gt;Simple operations&lt;/strong&gt; – Around 99% of the queries are direct key lookups&lt;/p&gt;
&lt;h3&gt;
  
  
  Schema Design
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;SEQUENCE&lt;/span&gt; &lt;span class="n"&gt;urls_id_seq&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;urls&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;BIGINT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;nextval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'urls_id_seq'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;short_code&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;UNIQUE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;long_url&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="n"&gt;TIMESTAMPTZ&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;UNIQUE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_urls_short_code&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;urls&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;short_code&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;Why this works:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;id&lt;/code&gt; is the source of truth (sequence-generated)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;short_code&lt;/code&gt; has unique index for fast &lt;strong&gt;O(log n)&lt;/strong&gt; lookups&lt;/li&gt;
&lt;li&gt;No index on &lt;code&gt;long_url&lt;/code&gt; (expensive, rarely queried)&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  The Core Problem: ID Generation
&lt;/h2&gt;

&lt;p&gt;Generating short codes sounds simple, but in practice you need IDs that:&lt;br&gt;
&lt;strong&gt;1.&lt;/strong&gt; Are globally &lt;strong&gt;unique&lt;/strong&gt; (no collisions)&lt;br&gt;
&lt;strong&gt;2.&lt;/strong&gt; Stay short (7 characters or less)&lt;br&gt;
&lt;strong&gt;3.&lt;/strong&gt; Don't require coordination between servers&lt;/p&gt;
&lt;h3&gt;
  
  
  Strategy: Sequence + Base62 Encoding
&lt;/h3&gt;

&lt;p&gt;Here's the actual implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ShortCodeGenerator&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ShortCodeGeneratorPort&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="no"&gt;BASE62&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
        &lt;span class="s"&gt;"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalArgumentException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ID must be positive"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="nc"&gt;StringBuilder&lt;/span&gt; &lt;span class="n"&gt;sb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;StringBuilder&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;remainder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;62&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;sb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;BASE62&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;charAt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;remainder&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
            &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;/=&lt;/span&gt; &lt;span class="mi"&gt;62&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;sb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;reverse&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why this is collision-free:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PostgreSQL sequence guarantees &lt;strong&gt;unique&lt;/strong&gt; IDs (1, 2, 3, ...)&lt;/li&gt;
&lt;li&gt;Base62 is a bijective function: unique ID -&amp;gt; unique code&lt;/li&gt;
&lt;li&gt;If ID1 != ID2, then Base62(ID1) != Base62(ID2)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No retry logic needed&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Capacity Analysis
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Length&lt;/th&gt;
&lt;th&gt;Possible URLs&lt;/th&gt;
&lt;th&gt;Years at 1k/sec&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;5 chars&lt;/td&gt;
&lt;td&gt;916 million&lt;/td&gt;
&lt;td&gt;29 years&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6 chars&lt;/td&gt;
&lt;td&gt;56.8 billion&lt;/td&gt;
&lt;td&gt;1,800 years&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7 chars&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;3.52 trillion&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;111,000 years&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;With 7 characters, we’re set for a while. We only need about 365 billion.&lt;/p&gt;




&lt;h2&gt;
  
  
  Caching
&lt;/h2&gt;

&lt;p&gt;At ~10k reads/sec, PostgreSQL was fine. But I knew the moment traffic spiked, the DB would start being the bottleneck.&lt;/p&gt;

&lt;p&gt;What surprised me the most was how visible the change became after adding cache.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Problem
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Every request:
1. App -&amp;gt; PostgreSQL: "SELECT * FROM urls WHERE short_code = 'aB3x'"
2. PostgreSQL -&amp;gt; Disk: Read from index + table
3. PostgreSQL -&amp;gt; App: Return result
4. App -&amp;gt; Client: 302 redirect

Latency: 5-10ms per request
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even with indexes, disk I/O is expensive and most users keep hitting the same short URLs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solution: Cache‑Aside with Redis
&lt;/h3&gt;

&lt;p&gt;The pattern is simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.&lt;/strong&gt; Try Redis first&lt;br&gt;
&lt;strong&gt;2.&lt;/strong&gt; If miss -&amp;gt; query in Database&lt;br&gt;
&lt;strong&gt;3.&lt;/strong&gt; Store in Redis for next time&lt;/p&gt;

&lt;p&gt;This gave me the best of both worlds: &lt;strong&gt;resilience&lt;/strong&gt; (if Redis dies, the system still works) and &lt;strong&gt;speed&lt;/strong&gt; (most reads never touch the DB).&lt;/p&gt;


&lt;h2&gt;
  
  
  API Design
&lt;/h2&gt;

&lt;p&gt;Keep it simple:&lt;/p&gt;
&lt;h3&gt;
  
  
  Create Short URL
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST /api/v1/shorten
Content-Type: application/json

{
  "url": "https://website.com/very/long/url"
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"shortCode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"aB3x"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Redirect
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /aB3x
GET /api/v1/aB3x
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Returns &lt;code&gt;302 Found&lt;/code&gt; with &lt;code&gt;Location: https://website.com/very/long/url&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why 302 instead of 301?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;301 &lt;strong&gt;(permanent)&lt;/strong&gt; gets cached by browsers -&amp;gt; no click tracking&lt;/li&gt;
&lt;li&gt;302 &lt;strong&gt;(temporary)&lt;/strong&gt; hits your server every time -&amp;gt; you can measure clicks or any metrics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a URL shortener &lt;strong&gt;with analytics&lt;/strong&gt;, 302 is the right choice.&lt;/p&gt;




&lt;h2&gt;
  
  
  Code Structure
&lt;/h2&gt;

&lt;p&gt;Here's the actual file structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;java&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lomeu&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&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="nc"&gt;UrlService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;java&lt;/span&gt;         &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;orchestration&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;       &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="o"&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="nc"&gt;UrlUseCase&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;java&lt;/span&gt;     &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inbound&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;       &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;           &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nc"&gt;UrlRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;java&lt;/span&gt;  &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outbound&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;           &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nc"&gt;ShortCodeGeneratorPort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;java&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nc"&gt;Url&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;java&lt;/span&gt;                    &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pure&lt;/span&gt; &lt;span class="n"&gt;domain&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;infrastructure&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&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="nc"&gt;UrlController&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;java&lt;/span&gt;      &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;HTTP&lt;/span&gt; &lt;span class="n"&gt;adapter&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="o"&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="nc"&gt;Database&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;java&lt;/span&gt;           &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt; &lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="o"&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="nc"&gt;JdbcUrlRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;java&lt;/span&gt;  &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;persistence&lt;/span&gt; &lt;span class="n"&gt;adapter&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="n"&gt;generator&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;       &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nc"&gt;ShortCodeGenerator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;java&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Base62&lt;/span&gt; &lt;span class="n"&gt;implementation&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nc"&gt;AppConfig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;java&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;
&lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nc"&gt;Main&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;java&lt;/span&gt;                        &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;shutdown&lt;/span&gt; &lt;span class="n"&gt;hook&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;The complete implementation at &lt;a href="https://github.com/lucaslomeu/url-shortener" rel="noopener noreferrer"&gt;github.com/lucaslomeu/url-shortener&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>systemdesign</category>
      <category>architecture</category>
      <category>java</category>
      <category>performance</category>
    </item>
    <item>
      <title>Arquitetura Fullstack com Angular 19 + Spring Boot</title>
      <dc:creator>Lucas Lomeu</dc:creator>
      <pubDate>Mon, 05 May 2025 11:11:21 +0000</pubDate>
      <link>https://forem.com/lucaslomeu/estudo-de-caso-arquitetura-de-um-app-fullstack-moderno-com-angular-19-e-spring-boot-3732</link>
      <guid>https://forem.com/lucaslomeu/estudo-de-caso-arquitetura-de-um-app-fullstack-moderno-com-angular-19-e-spring-boot-3732</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Neste post, compartilho um pouco da experiência de desenvolver uma aplicação fullstack real com Angular 19, Spring Boot e Docker.&lt;br&gt;&lt;br&gt;
O objetivo não é ensinar passo a passo, mas sim apresentar as decisões técnicas, aprendizados e desafios enfrentados ao longo do projeto.&lt;br&gt;&lt;br&gt;
Ao abordar tópicos como autenticação JWT, arquitetura, integração entre frontend e backend e containerização.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  📌 Sobre o projeto
&lt;/h2&gt;

&lt;p&gt;O &lt;strong&gt;Mony&lt;/strong&gt; é uma aplicação web para controle de assinaturas e finanças pessoais. A ideia é oferecer uma forma simples de:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cadastrar serviços recorrentes (como Netflix, Spotify, etc.)&lt;/li&gt;
&lt;li&gt;Visualizar todos os gastos mensais&lt;/li&gt;
&lt;li&gt;Ter uma visão clara sobre o orçamento&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O foco desse projeto foi &lt;strong&gt;estruturar um app fullstack moderno&lt;/strong&gt; (por isso a escolha do Angular 19) com boas práticas de frontend, backend e containerização com Docker&lt;/p&gt;




&lt;h2&gt;
  
  
  🔧 Tecnologias utilizadas
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; Angular 19 + Tailwind CSS v4&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend:&lt;/strong&gt; Java 11 - Spring Boot + Spring Security + JWT + Spring Data JPA&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Banco de dados:&lt;/strong&gt; PostgreSQL 15&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Containerização:&lt;/strong&gt; Docker + Docker Compose&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧱 Arquitetura da aplicação
&lt;/h2&gt;

&lt;p&gt;Visão geral da arquitetura lógica da aplicaçã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%2Fgfdfyzbbfr5oo6ri86ct.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%2Fgfdfyzbbfr5oo6ri86ct.png" alt="Arquitetura da aplicação" width="800" height="265"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🧬 Modelo de dados
&lt;/h2&gt;

&lt;p&gt;As entidades principais do sistema são &lt;code&gt;MonyUser&lt;/code&gt;, &lt;code&gt;Subscription&lt;/code&gt;, &lt;code&gt;Category&lt;/code&gt; e &lt;code&gt;Address&lt;/code&gt;. Veja como elas se relacionam:&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%2Ftdu54c16t08dkwfmuyxe.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%2Ftdu54c16t08dkwfmuyxe.png" alt="Modelo de Dados do Mony" width="607" height="828"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🗂️ Estrutura do Projeto
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mony/
├── server/        # Backend Spring Boot
│   └── ...        # Controllers, DTOs, Repositories, etc.
├── client/        # Frontend Angular 19
│   └── ...        # Features, Shared Modules, Layout
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A descrição completa das pastas e suas responsabilidades está disponível no &lt;a href="https://github.com/lucaslomeu/mony" rel="noopener noreferrer"&gt;README do repositório&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧰 Uso do Lombok no backend
&lt;/h2&gt;

&lt;p&gt;Durante o desenvolvimento do backend, utilizei o &lt;a href="https://projectlombok.org/" rel="noopener noreferrer"&gt;Project Lombok&lt;/a&gt; para reduzir o boilerplate nas classes Java, especialmente nas entidades, DTOs e serviços.&lt;/p&gt;

&lt;p&gt;Com anotações como &lt;code&gt;@Getter&lt;/code&gt;, &lt;code&gt;@Setter&lt;/code&gt;, &lt;code&gt;@NoArgsConstructor&lt;/code&gt;, &lt;code&gt;@AllArgsConstructor&lt;/code&gt; e &lt;code&gt;@Builder&lt;/code&gt;, consegui manter o código mais limpo, legível e focado na lógica de negócio, evitando repetições desnecessárias de métodos.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Além de deixar as classes mais enxutas, o uso do Lombok contribuiu para a produtividade e organização geral do projeto.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🔐 Autenticação JWT com Spring Security
&lt;/h2&gt;

&lt;p&gt;Implementei autenticação e autorização com JWT no backend, protegendo todos os endpoints sensíveis. A geração e validação dos tokens são feitas com filtro personalizado no Spring Security.&lt;/p&gt;

&lt;p&gt;No frontend, o Angular armazena o token localmente com LocalStorage e utiliza um &lt;code&gt;HTTPInterceptor&lt;/code&gt; para enviá-lo automaticamente em cada requisição autenticada.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;&lt;code&gt;Principal&lt;/code&gt; no backend&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;Durante a implementação, tive que decidir como lidar com os dados do usuário autenticado no backend.  &lt;/p&gt;

&lt;p&gt;Inicialmente, pensei em enviar o ID do usuário em cada requisição ou armazenar algo no &lt;code&gt;LocalStorage&lt;/code&gt;, mas isso abriria espaço para falhas de segurança.&lt;/p&gt;

&lt;p&gt;Foi nesse momento que conheci a interface &lt;code&gt;Principal&lt;/code&gt; do Spring — algo novo pra mim até então. Ela resolvia exatamente o que eu buscava: deixava o &lt;strong&gt;backend 100% responsável por identificar o usuário autenticado&lt;/strong&gt;, com base no JWT.  &lt;/p&gt;

&lt;p&gt;Isso permitiu que cada controller acessasse diretamente o contexto do usuário logado sem depender de nenhuma informação adicional do frontend.  &lt;/p&gt;

&lt;p&gt;Resultado: código mais limpo, seguro e desacoplado.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A partir disso, todos os controllers que precisam de contexto do usuário simplesmente recebem o &lt;code&gt;Principal&lt;/code&gt; como parâmetro. Com isso, o backend consegue filtrar ou associar dados automaticamente ao usuário autenticado, mantendo a integridade dos dados e a segurança da aplicação.&lt;/p&gt;




&lt;h2&gt;
  
  
  📦 Docker Compose: backend + frontend + PostgreSQL
&lt;/h2&gt;

&lt;p&gt;Para facilitar o desenvolvimento e isolar os serviços, configurei um ambiente completo com Docker Compose.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PostgreSQL 15 (banco de dados)&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Spring Boot (backend)&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Angular 19 (frontend)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E com o comando abaixo, toda a aplicação sobe em containers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose up &lt;span class="nt"&gt;--build&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧠 Aprendizados e desafios técnicos
&lt;/h2&gt;

&lt;p&gt;Enquanto desenvolvia o Mony, tive a oportunidade de aprofundar e aplicar conceitos importantes em várias áreas do stack fullstack moderno:&lt;/p&gt;

&lt;h3&gt;
  
  
  🔷 Frontend (Angular 19)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Estruturei a aplicação com lazy loading e arquitetura modular por feature, seguindo boas práticas para escalabilidade.&lt;/li&gt;
&lt;li&gt;Usei o &lt;strong&gt;Tailwind CSS v4&lt;/strong&gt; para estilização rápida, com foco em produtividade e responsividade.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Como venho de projetos com versões mais antigas do Angular (8, 11, 14), esse projeto foi também uma oportunidade para aplicar &lt;strong&gt;as novidades das versões mais recentes&lt;/strong&gt;. Entre os destaques:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://angular.dev/api/core/inject" rel="noopener noreferrer"&gt;&lt;code&gt;inject()&lt;/code&gt;&lt;/a&gt;: substitui a injeção de dependência tradicional via construtor. O código ficou mais limpo e menos verboso, especialmente em componentes simples ou standalone.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://angular.dev/api/core/computed" rel="noopener noreferrer"&gt;&lt;code&gt;@computed()&lt;/code&gt;&lt;/a&gt;: facilita a criação de propriedades derivadas e reativas sem depender de &lt;code&gt;rxjs&lt;/code&gt;, tornando o código mais declarativo, previsível e legível.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://angular.dev/api/core/@for" rel="noopener noreferrer"&gt;&lt;code&gt;@for&lt;/code&gt;&lt;/a&gt; e &lt;a href="https://angular.dev/api/core/@if" rel="noopener noreferrer"&gt;@if&lt;/a&gt;: evoluções das diretivas estruturais (&lt;code&gt;*ngFor&lt;/code&gt;, &lt;code&gt;*ngIf&lt;/code&gt;) que tornam o HTML mais moderno e direto, eliminando a necessidade de blocos &lt;code&gt;ng-template&lt;/code&gt; e melhorando a performance.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://angular.dev/api/core/resource" rel="noopener noreferrer"&gt;resource()&lt;/a&gt;: uma das features que mais gostei (mesmo ainda sendo experimental). Permite declarar &lt;code&gt;loader&lt;/code&gt; e &lt;code&gt;request&lt;/code&gt; de forma reativa e integrada ao ciclo de vida, gerenciando chamadas assíncronas com muito menos código, utilizando &lt;code&gt;signals&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://angular.dev/api/core/effect" rel="noopener noreferrer"&gt;effect()&lt;/a&gt;: executa funções automaticamente sempre que um &lt;code&gt;signal&lt;/code&gt; dependente muda de valor. Usei no serviço de CEP, por exemplo, para atualizar campos dinamicamente conforme o usuário escolhia um estado, assim o DOM respondia instantaneamente.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  🔶 Backend (Spring Boot)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Configuração completa do Spring Security com autenticação via JWT&lt;/li&gt;
&lt;li&gt;Implementação de filtros personalizados para validar tokens&lt;/li&gt;
&lt;li&gt;Uso da interface &lt;code&gt;Principal&lt;/code&gt; para identificar automaticamente o usuário logado sem expor dados no frontend&lt;/li&gt;
&lt;li&gt;Mapeamento e relacionamento de entidades com JPA, incluindo um cenário N:N usando &lt;code&gt;@ManyToMany&lt;/code&gt; com &lt;code&gt;@JoinTable&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Separação clara entre DTOs, entidades, serviços e repositórios&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;Você pode conferir o código completo aqui:&lt;br&gt;&lt;br&gt;
🔗 &lt;a href="https://github.com/lucaslomeu/mony" rel="noopener noreferrer"&gt;Repositório no GitHub - Mony&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  📋 Resumo técnico
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;✅ Stack: Angular 19, Spring Boot, PostgreSQL&lt;/li&gt;
&lt;li&gt;🧠 Auth: JWT + Spring Security + &lt;code&gt;Principal&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;🐳 Dev: Docker Compose com 3 containers&lt;/li&gt;
&lt;li&gt;🧰 Extras: Lombok, Tailwind, ng2-charts&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>angular</category>
      <category>jwt</category>
      <category>springboot</category>
      <category>docker</category>
    </item>
    <item>
      <title>Linux Básico: comandos essenciais do terminal</title>
      <dc:creator>Lucas Lomeu</dc:creator>
      <pubDate>Mon, 13 Nov 2023 11:44:37 +0000</pubDate>
      <link>https://forem.com/lucaslomeu/basic-linux-ch3</link>
      <guid>https://forem.com/lucaslomeu/basic-linux-ch3</guid>
      <description>&lt;h2&gt;
  
  
  LINUX COMMAND LINE
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Listing
&lt;/h3&gt;

&lt;p&gt;O comando &lt;code&gt;ls&lt;/code&gt; é usado para listar arquivos e diretórios. Aqui estão algumas opções comuns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;-a&lt;/strong&gt; ou &lt;strong&gt;--all&lt;/strong&gt;: Lista inclusive arquivos ocultos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;-l&lt;/strong&gt;: Fornece informações extras.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;-h&lt;/strong&gt;: Formata a saída de forma legível.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;-R&lt;/strong&gt;: Lista recursivamente.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;ls [path] -a -l -h -R&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Exemplo:&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;ls&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="nt"&gt;-h&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Change Directory
&lt;/h3&gt;

&lt;p&gt;O comando cd é utilizado para navegar entre pastas. Para voltar uma pasta, use ...&lt;br&gt;
Para voltar uma pasta, use ..&lt;/p&gt;

&lt;p&gt;Exemplo:&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;cd&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;path]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Copy
&lt;/h3&gt;

&lt;p&gt;O comando cp copia arquivos ou pastas para o destino. A opção -r indica que a cópia deve ser feita de forma recursiva.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cp path ou file -r&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Exemplo:&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;cp&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;origem] &lt;span class="o"&gt;[&lt;/span&gt;destino] &lt;span class="nt"&gt;-r&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Move
&lt;/h3&gt;

&lt;p&gt;O comando mv move arquivos ou pastas para o destino e pode ser usado para renomear. Utilize com cuidado.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;path ou file] &lt;span class="o"&gt;[&lt;/span&gt;dest] &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Remove
&lt;/h3&gt;

&lt;p&gt;Apaga arquivos ou diretórios.&lt;br&gt;
Exemplo:&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;rm&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;path ou file] &lt;span class="o"&gt;[&lt;/span&gt;dest] &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Make directory
&lt;/h3&gt;

&lt;p&gt;Cria pasta, passando o destino completo ou apenas o nome do arquivo.&lt;/p&gt;

&lt;p&gt;Exemplo:&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;mkdir&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;path]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Remove Make directory
&lt;/h3&gt;

&lt;p&gt;Apaga pastas, passando o destino completo ou apenas o nome do arquivo.&lt;/p&gt;

&lt;p&gt;Exemplo:&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;rmdir&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;path]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Empty File
&lt;/h3&gt;

&lt;p&gt;Cria um arquivo vazio com nome informado no parâmetro [file].&lt;/p&gt;

&lt;p&gt;Exemplo:&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;touch&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;file]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Text Editor.
&lt;/h3&gt;

&lt;p&gt;Abre Editor de texto (nano ou vim).&lt;br&gt;
Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano &lt;span class="o"&gt;[&lt;/span&gt;file]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ou&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vi &lt;span class="o"&gt;[&lt;/span&gt;file]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Super user
&lt;/h3&gt;

&lt;p&gt;Usado para executar comandos com permissão elevada.&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;sudo&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;comando]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Clear
&lt;/h3&gt;

&lt;p&gt;Limpar a interface do terminal&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;clear
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>linux</category>
      <category>terminal</category>
      <category>beginners</category>
      <category>learning</category>
    </item>
    <item>
      <title>Promises em JavaScript: entendendo o básico</title>
      <dc:creator>Lucas Lomeu</dc:creator>
      <pubDate>Sun, 13 Mar 2022 17:03:30 +0000</pubDate>
      <link>https://forem.com/lucaslomeu/entendendo-promises-2al5</link>
      <guid>https://forem.com/lucaslomeu/entendendo-promises-2al5</guid>
      <description>&lt;h1&gt;
  
  
  PROMISES
&lt;/h1&gt;

&lt;p&gt;Antes de entendermos as &lt;code&gt;Promises&lt;/code&gt;, temos de conhecer as diferenças entre comportamentos &lt;code&gt;síncronos&lt;/code&gt; e &lt;code&gt;assíncronos&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Síncrono e Assíncrono
&lt;/h2&gt;

&lt;p&gt;Como o próprio nome pode nos ajudar a deduzir, &lt;strong&gt;síncrono&lt;/strong&gt; acontece em sincronia, ou seja, que ocorre em mesmo tempo que outra coisa. Já &lt;strong&gt;assíncrono&lt;/strong&gt; é o oposto, é algo que não acontece junto com outra coisa. Podemos exemplificar esses comportamentos síncronos e assíncronos, como uma chamada de telefone e envio de e-mail, respectivamente.&lt;/p&gt;

&lt;p&gt;Sabendo o básico, podemos afirmar que o &lt;strong&gt;Javascript&lt;/strong&gt; é &lt;strong&gt;síncrono&lt;/strong&gt;, sendo executado linearmente de cima para baixo. Isso se deve ao fato que ela é uma linguagem &lt;code&gt;Single Thread&lt;/code&gt;, então cada linha de comando só será executada quando a anterior é finalizada.&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Primeira linha&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Segunda linha&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Terceira linha&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Quarta linha&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Quinta linha&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;Sendo assim, o código acima quando executado, nos retorna:&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;Primeira&lt;/span&gt; &lt;span class="nx"&gt;linha&lt;/span&gt;
&lt;span class="nx"&gt;Segunda&lt;/span&gt; &lt;span class="nx"&gt;linha&lt;/span&gt;
&lt;span class="nx"&gt;Terceira&lt;/span&gt; &lt;span class="nx"&gt;linha&lt;/span&gt;
&lt;span class="nx"&gt;Quarta&lt;/span&gt; &lt;span class="nx"&gt;linha&lt;/span&gt;
&lt;span class="nx"&gt;Quinta&lt;/span&gt; &lt;span class="nx"&gt;linha&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No Javascript temos a função assíncrona &lt;code&gt;setTimeout()&lt;/code&gt;, onde no primeiro parâmetro ela espera uma função e no segundo o tempo que após ser feita a chamada da função, ela será executada, isso em milissegundos.&lt;/p&gt;

&lt;p&gt;Sendo assim, vamos analisar o código 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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Primeira linha&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Segunda linha&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;setTimeout&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Terceira linha&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Quarta linha&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Quinta linha&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;Caso a função &lt;code&gt;setTimeout()&lt;/code&gt; fosse &lt;em&gt;síncrona&lt;/em&gt;, deveriamos ter o retorno abaixo, já que está sendo chamado na terceira linha:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Primeira linha
Segunda linha
setTimeout
Terceira linha
Quarta linha
Quinta linha
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Porém, ela é uma função que não acontece junto com outra coisa -&lt;em&gt;assíncrona&lt;/em&gt; - ela só sera retornada com uma condição ou parâmetro, que no caso, é ser executada após 2 segundos, nos retornando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Primeira linha
Segunda linha
Terceira linha
Quarta linha
Quinta linha
setTimeout
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ou seja, ela executa todas as outras linhas de maneira &lt;em&gt;síncrona&lt;/em&gt;, quando chega no &lt;code&gt;setTimeout()&lt;/code&gt;, ela é entregue para uma request &lt;strong&gt;separada&lt;/strong&gt; que é executada fora da thread do Javascript &lt;em&gt;- lembrando que o código que escrevemos é executado em uma única thread -&lt;/em&gt; fazendo com que o restante continue a ser executado.&lt;/p&gt;

&lt;p&gt;Agora já com o conhecimento de &lt;strong&gt;síncrono/assíncrono&lt;/strong&gt;, podemos tratar das &lt;code&gt;Promises&lt;/code&gt;. Como o próprio nome diz, é uma promessa que pode ou não estar disponível em algum momento, sendo assim, ela possui um comportamento &lt;strong&gt;assíncrono&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Promise é um objeto que possui três possíveis estados, sendo eles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pending&lt;/strong&gt; – Estado inicial, pendente de execução&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fulfilled&lt;/strong&gt; – Concluido com sucesso&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rejected&lt;/strong&gt; – Ocorreu algum erro&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A mesma recebe &lt;strong&gt;dois parâmetros&lt;/strong&gt;, sendo eles comumente chamados de &lt;code&gt;resolve e reject&lt;/code&gt;, sendo assim, apenas um dos métodos de tratamento será chamado. Para acessar a resposta dessa promisse, temos o &lt;code&gt;.then&lt;/code&gt; e o &lt;code&gt;.catch&lt;/code&gt;, sendo responsáveis por tratar a resposta e o erro respectivamente.&lt;/p&gt;

&lt;p&gt;O método &lt;code&gt;.then&lt;/code&gt; irá registrar um _callback _de &lt;strong&gt;sucesso&lt;/strong&gt; e é comum executar duas ou mais operações assíncronas consecutivas, executando a ação posterior apenas quando a anterior for bem sucedida, isso é possível realizando o encadeamento do método &lt;code&gt;.then&lt;/code&gt;, onde o mesmo retorna uma nova promise diferente da original.&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;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Inicio da Promise&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;numero&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;numero&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Primeiro valor: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Valor somado de 5: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;newValue&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="s2"&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 código foi chamado a função construtora passando os dois parâmetros como argumento e a chamada de uma função callback.&lt;br&gt;
Logo de  início já é executado nosso primeiro &lt;code&gt;console.log&lt;/code&gt; e o armazenamento de &lt;em&gt;numero&lt;/em&gt; em uma constante, recebendo o valor 10, logo após chamamos nosso &lt;code&gt;resolve(numero)&lt;/code&gt;, passando como resolvida nossa promise e ela recebe esse número.&lt;/p&gt;

&lt;p&gt;Agora devemos tratar esse resultado fazendo a chamada do nosso primeiro &lt;code&gt;.then&lt;/code&gt; onde o mesmo recebe um parâmetro &lt;code&gt;value&lt;/code&gt;, esse valor recebe o que foi passado em resolve, logo &lt;code&gt;value&lt;/code&gt; equivale a &lt;code&gt;numero&lt;/code&gt;, sendo assim, chamamos o &lt;code&gt;console.log&lt;/code&gt; desse &lt;code&gt;value&lt;/code&gt; e retornamos ele para que possamos utilizar no próximo encadeamento de &lt;code&gt;.then&lt;/code&gt;, onde iremos tratar o retorno anterior.&lt;br&gt;
Para diferenciarmos, foi passado como parâmetro agora &lt;code&gt;newValue&lt;/code&gt; onde o mesmo recebeu o valor anterior e será tratado no console, sendo acrescido de 5.&lt;/p&gt;

&lt;p&gt;O resultado final desse 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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Inicio da Promise&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;numero&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;numero&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Primeiro valor: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Valor somado de 5: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;newValue&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="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora iremos tratar a promise caso fosse chamado o &lt;code&gt;reject&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Inicio da Promise&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;numero&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Número não identificado&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="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Primeiro valor: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Valor somado de 5: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;newValue&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="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="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Houve um erro: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como fazemos a chamada de &lt;code&gt;reject()&lt;/code&gt;, a função logo irá chamar o método &lt;code&gt;.catch&lt;/code&gt; que também recebe um parâmetro e o mesmo é retornado no &lt;code&gt;console.log()&lt;/code&gt;, renderizando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Inicio da Promise
Houve um erro: Número não identificado
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Um método muito utilizado, é a API fetch que realiza requisições HTTP através de Promises.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>promises</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Todo List com React: passo a passo</title>
      <dc:creator>Lucas Lomeu</dc:creator>
      <pubDate>Tue, 16 Nov 2021 23:36:56 +0000</pubDate>
      <link>https://forem.com/lucaslomeu/criando-todolist-com-reactjs-1k88</link>
      <guid>https://forem.com/lucaslomeu/criando-todolist-com-reactjs-1k88</guid>
      <description>&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Nesse tutorial iremos desenvolver um &lt;strong&gt;"TodoList"&lt;/strong&gt; em ReactJs da maneira mais simples possível, sendo assim, não iremos focar em estilização do mesmo. Recomendo que tenha noção básica de &lt;em&gt;JavaScript&lt;/em&gt;.&lt;/p&gt;

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

&lt;p&gt;Para iniciarmos o projeto, abra seu terminal e use o seguinte comando&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-react-app todolist
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Após a criação, dirija-se até o diretório e abra seu VisualStudio Code&lt;/p&gt;

&lt;h2&gt;
  
  
  Limpando arquivos desnecessários
&lt;/h2&gt;

&lt;p&gt;Para esse tutorial, poderemos remover alguns arquivos desnecessários de nossa aplicação.&lt;/p&gt;

&lt;p&gt;Na pasta &lt;strong&gt;src&lt;/strong&gt;, remova os arquivos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;App.test.js
index.css
logo.svg
reportWebVitals.js
setupTests.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você também deverá retirar a importação desses arquivos no &lt;strong&gt;App.js&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Parte 01
&lt;/h2&gt;

&lt;p&gt;Logo de início deveremos fazer a importação do &lt;strong&gt;useState&lt;/strong&gt; no &lt;strong&gt;App.js&lt;/strong&gt;, pois estamos desenvolvendo um &lt;strong&gt;TodoList&lt;/strong&gt;, ou seja, teremos alterações de estado (adição, remoção) de itens na lista de afazeres.&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;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="s1"&gt;react&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;Assim, estaremos aptos a utilizar o Hook.&lt;/p&gt;

&lt;p&gt;Agora, deveremos criar o estado inicial da lista, para isso, utilizamos o &lt;strong&gt;useState&lt;/strong&gt;, sendo um hook que retorna um array com dois valores, o primeiro é o estado atual e imutável, já o segundo uma função que irá alterar o estado do componente quando a mesma for ativada.&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="p"&gt;[&lt;/span&gt; &lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setTodo&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;-Todo&lt;/strong&gt; representa o primeiro valor, logo o estado atual.&lt;br&gt;
&lt;strong&gt;-setTodo&lt;/strong&gt; representa o segundo valor, logo a função que irá realizar as alterações. &lt;em&gt;(Por padrão costumamos nomear o segundo valor com "set" e logo após o nome dado ao primeiro valor).&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;O valor entre parenteses do &lt;em&gt;useState&lt;/em&gt; representa o valor &lt;strong&gt;INICIAL&lt;/strong&gt; do estado, como estamos criando uma lista de afazeres, o valor inicial é um Array que poderá conter vários itens.&lt;/p&gt;

&lt;p&gt;Agora iremos criar outro estado para os &lt;strong&gt;novos&lt;/strong&gt; itens a serem adicionados nesse array:&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;newTodo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setNewTodo&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="dl"&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;Dessa vez o estado inicial é uma &lt;em&gt;string&lt;/em&gt; vazia, pois é o valor inicial do input do tipo texto que iremos inserir na nossa aplicação.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Parte 02
&lt;/h2&gt;

&lt;p&gt;Com nossos estados criados, iremos desenvolver o que será renderizado, para isso adicionaremos um &lt;strong&gt;input&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;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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setTodo&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;newTodo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setNewTodo&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="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Todo&lt;/span&gt; &lt;span class="nx"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&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;input&lt;/span&gt;
        &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;newTodo&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{(&lt;/span&gt;&lt;span class="nx"&gt;item&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;setNewTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&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;value&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;/&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;blockquote&gt;
&lt;p&gt;Para envolvermos várias tags &lt;em&gt;HTML&lt;/em&gt;, podemos utilizar uma &lt;strong&gt;div&lt;/strong&gt; ou então fragments &lt;strong&gt;&amp;lt;&amp;gt;&amp;lt;/&amp;gt;&lt;/strong&gt; e todo o conteudo dentro do mesmo.&lt;/p&gt;

&lt;p&gt;Criamos um input do tipo texto; no valor passamos o &lt;em&gt;newTodo&lt;/em&gt;, sendo identico ao do estado já criado e onChange passamos uma função, onde conforme o estado é alterado, ele atualiza seu valor (&lt;em&gt;value={newTodo}&lt;/em&gt;).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ou seja, o valor (texto) atual presente no input criado, será adicionado ao nosso estado, com isso poderemos futuramente fazer com que esse valor seja renderizado na lista de afazeres.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Para que possamos adicionar esse &lt;em&gt;valor&lt;/em&gt; em uma lista, iremos adicionar um botão que ao ser clicado, chamará a função &lt;em&gt;addNewTodo&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addNewTodo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setTodo&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newTodo&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="nf"&gt;setNewTodo&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Na &lt;strong&gt;primeira&lt;/strong&gt; linha, chamamos a função do nosso primeiro estado, onde seu valor inicial é um array vazio e definimos agora que seu valor será tudo que estava presente nesse array antes &lt;em&gt;(para isso utilizamos o spread)&lt;/em&gt;, e no segundo parâmetro passamos o &lt;em&gt;newTodo&lt;/em&gt;, ou seja, toda alteração que for feita nesse estado, após ser clicado no botão de "Adicionar", essa alteração/valor será adicionado ao nosso estado inicial da aplicação (todo).&lt;/p&gt;

&lt;p&gt;Já na &lt;strong&gt;segunda&lt;/strong&gt; linha, definimos que ao adicionar o novo valor no nosso estado, não podemos deixar o &lt;em&gt;valor/texto&lt;/em&gt; do nosso input com o que foi digitado, devemos retirar tudo e transformar nosso estado inicial em uma string vazia novamente.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;O &lt;strong&gt;botão&lt;/strong&gt; a ser criado:&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;addNewTodo&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;Adicionar&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Recapitulando&lt;/strong&gt;: Ao ser clicado, chamará nossa função &lt;strong&gt;addNewTodo()&lt;/strong&gt;, que irá adicionar o novo valor ao nosso estado atual e logo após resetar o valor escrito no input.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Parte 03
&lt;/h2&gt;

&lt;p&gt;Agora iremos renderizar todos esses valores em uma lista, para isso utilizaremos o &lt;strong&gt;map&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ul&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;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&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;item&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
       &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/li&lt;/span&gt;&lt;span class="err"&gt;&amp;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="sr"&gt;/ul&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ou seja, a cada item/todo/valor novo adicionado ao nosso array de &lt;em&gt;todos&lt;/em&gt;, o map irá percorrer essa lista de array e renderizar um por um em forma de lista. No código acima, passamos como parâmetro &lt;strong&gt;item&lt;/strong&gt;, sendo assim, cada &lt;strong&gt;item&lt;/strong&gt; presente no &lt;strong&gt;todo&lt;/strong&gt;, será renderizado um a um, até que o ultimo seja renderizado.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Escrevemos o código entre chaves pra mostrar que se trata de um código javascript e não HTML.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Com isso, chegamos a uma tela semelhante a essa:&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%2Fxp6ihr254ocre5jz456b.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%2Fxp6ihr254ocre5jz456b.png" alt="TodoList Render" width="291" height="219"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Parte 04
&lt;/h2&gt;

&lt;p&gt;Assim como podemos adicionar itens/afazeres ao nosso array, podemos também excluir o mesmo.&lt;/p&gt;

&lt;p&gt;Sendo assim, iremos criar dentro do &lt;strong&gt;map&lt;/strong&gt; um botão para que seja renderizado a cada item.&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;removeTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&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;Deletar&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como podemos ver, ao ser clicado ele chama a função &lt;em&gt;removeTodo&lt;/em&gt; que tem como parâmetro &lt;em&gt;index&lt;/em&gt;. Esse parâmetro nós podemos identificar ele no próprio map, é o segundo valor a ser passado na função.&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="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&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;item&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;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;removeTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&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;Deletar&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&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;/li&lt;/span&gt;&lt;span class="err"&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;Deveremos passar esse parâmetro também na função, para que possamos identificar o item. &lt;strong&gt;Ele funciona como identificador único, ID&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;function&lt;/span&gt; &lt;span class="nf"&gt;removeTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&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;tmpArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="nx"&gt;tmpArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;splice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&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="nf"&gt;setTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tmpArray&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;Criamos uma variável &lt;em&gt;tmpArray&lt;/em&gt;, que define um array temporário, onde utilizamos o &lt;em&gt;spread&lt;/em&gt; para adicionar tudo que contemos em nossa lista.&lt;/p&gt;

&lt;p&gt;Utilizamos o &lt;em&gt;splice&lt;/em&gt; e passamos como parâmetro o &lt;em&gt;index&lt;/em&gt; (identificador único que utilizamos como parâmetro na função e que passamos ele no map) e definimos que ele irá retirar apenas um item a partir do index 1.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;O método splice() altera o conteúdo de uma lista, adicionando novos elementos enquanto remove elementos antigos.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;E para finalizar, definimos o novo valor do estado &lt;em&gt;(setTodo)&lt;/em&gt;, com o valor do nosso array temporário &lt;em&gt;tmpArray&lt;/em&gt;, onde já foram feitas as modificações de exclusão de item.&lt;/p&gt;

&lt;h4&gt;
  
  
  Resultado da renderização
&lt;/h4&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%2Ff1hk784yui4qhx6h2lig.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%2Ff1hk784yui4qhx6h2lig.png" alt="TodoList Render" width="297" height="221"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Código Final
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&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="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setTodo&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;newTodo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setNewTodo&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="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addNewTodo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setTodo&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newTodo&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="nf"&gt;setNewTodo&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="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;removeTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&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;tmpArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="nx"&gt;tmpArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;splice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&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="nf"&gt;setTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tmpArray&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;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Todo&lt;/span&gt; &lt;span class="nx"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&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;input&lt;/span&gt;
        &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;newTodo&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{(&lt;/span&gt;&lt;span class="nx"&gt;item&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;setNewTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&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;value&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;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;addNewTodo&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;Adicionar&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&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;ul&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;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&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;item&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;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;removeTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&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;Deletar&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&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;/li&lt;/span&gt;&lt;span class="err"&gt;&amp;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="sr"&gt;/ul&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;/&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;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>react</category>
      <category>javascript</category>
      <category>braziliandevs</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
