<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ React - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Aprenda a codificar - de graça. Tutoriais de programação em Python, JavaScript, Linux e muito mais. ]]>
        </description>
        <link>https://www.freecodecamp.org/portuguese/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ React - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/portuguese/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Tue, 19 May 2026 10:03:02 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/portuguese/news/tag/react/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Ficha informativa de React com exemplos reais ]]>
                </title>
                <description>
                    <![CDATA[ Elaborei uma ficha informativa visual e abrangente para ajudá-lo a dominar todos os principais conceitos e recursos da biblioteca do React. > Nota da tradução: este texto foi escrito em 2021. Nos últimos três anos, algumas modificações do React podem ter tornado diversas partes deste artigo obsoletas. Criei esta ficha ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/ficha-informativa-de-react-com-exemplos-reais/</link>
                <guid isPermaLink="false">667721c279dc5c03cfad5133</guid>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Filipe Virgínio Vital Torres Barbosa ]]>
                </dc:creator>
                <pubDate>Wed, 02 Apr 2025 00:57:08 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2024/12/the-react-cheatsheet-for-2021-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/react-cheatsheet-with-real-world-examples/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">The React Cheatsheet for 2021‬ (+ Real-World Examples)</a>
      </p><p>Elaborei uma ficha informativa visual e abrangente para ajudá-lo a dominar todos os principais conceitos e recursos da biblioteca do React.</p><blockquote>Nota da tradução: este texto foi escrito em 2021. Nos últimos três anos, algumas modificações do React podem ter tornado diversas partes deste artigo obsoletas.</blockquote><p><strong><strong>Criei es</strong>t<strong>a f</strong>icha informativa <strong>para ajudá-lo a otimizar seu aprendizado de React no menor tempo possível.</strong></strong></p><p>Ela inclui vários exemplos práticos para ilustrar cada recurso da biblioteca e como ela funciona usando padrões que você pode aplicar em seus próprios projetos.</p><p>Junto com cada trecho de código, adicionei muitos comentários úteis. Se você ler esses comentários, verá o que cada linha de código faz, como os diferentes conceitos se relacionam entre si e obterá um entendimento mais completo de como o React pode ser usado.</p><p>Observe que as palavras-chave particularmente úteis para você conhecer como desenvolvedor do React estão destacadas em negrito. Portanto, fique atento a elas.</p><ul><li>Guia de referência rápida para revisar quando e como quiser</li><li>Inúmeros de trechos de código copiáveis para facilitar a reutilização</li><li>Leia este enorme guia onde for melhor para você. No trem, na sua mesa, na fila... em qualquer lugar.</li></ul><p>Há muitas coisas ótimas para tratarmos. Então, vamos começar.</p><blockquote>Deseja executar qualquer um dos trechos de código abaixo? Crie uma aplicação em React para experimentar qualquer um desses exemplos usando a ferramenta on-line (gratuita) CodeSandbox. Você pode fazer isso instantaneamente visitando <a href="https://react.new/">react.new</a>.</blockquote><h2 id="sum-rio"><strong>Sumário</strong></h2><h3 id="fundamentos-do-react"><strong>Fundamentos do React</strong></h3><ul><li><a href="https://www.freecodecamp.org/news/react-cheatsheet-with-real-world-examples/#jsx-elements">Elementos JSX</a></li><li><a href="https://www.freecodecamp.org/news/react-cheatsheet-with-real-world-examples/#components-and-props">Componentes e <em>props</em></a></li><li><a href="https://www.freecodecamp.org/news/react-cheatsheet-with-real-world-examples/#lists-and-keys">Listas e chaves</a></li><li><a href="https://www.freecodecamp.org/news/react-cheatsheet-with-real-world-examples/#event-listeners-and-handling-events">Ouvintes de eventos e tratamento de eventos</a></li></ul><h3 id="hooks-essenciais-do-react"><strong>Hooks essenciais do React</strong></h3><ul><li><a href="https://www.freecodecamp.org/news/react-cheatsheet-with-real-world-examples/#state-and-usestate">State e useState</a></li><li><a href="https://www.freecodecamp.org/news/react-cheatsheet-with-real-world-examples/#side-effects-and-useeffect">Efeitos colaterais e useEffect</a></li><li><a href="https://www.freecodecamp.org/news/react-cheatsheet-with-real-world-examples/#refs-and-useref">Refs e useRef</a></li></ul><h3 id="hooks-e-desempenho"><strong>Hooks e desempenho</strong></h3><ul><li><a href="https://www.freecodecamp.org/news/react-cheatsheet-with-real-world-examples/#preventing-re-renders-and-react-memo">Prevenção de novas renderizações e React.memo</a></li><li><a href="https://www.freecodecamp.org/news/react-cheatsheet-with-real-world-examples/#callback-functions-and-usecallback">Funções de <em>callback</em> e useCallback</a></li><li><a href="https://www.freecodecamp.org/news/react-cheatsheet-with-real-world-examples/#memoization-and-usememo">Memoização e useMemo</a></li></ul><h3 id="hooks-avan-ados-do-react"><strong>Hooks avançados do React</strong></h3><ul><li><a href="https://www.freecodecamp.org/news/react-cheatsheet-with-real-world-examples/#context-and-usecontext">Contexto e useContext</a></li><li><a href="https://www.freecodecamp.org/news/react-cheatsheet-with-real-world-examples/#reducers-and-usereducer">Redutores e useReducer</a></li><li><a href="https://www.freecodecamp.org/news/react-cheatsheet-with-real-world-examples/#writing-custom-hooks">Escrevendo hooks personalizados</a></li><li><a href="https://www.freecodecamp.org/news/react-cheatsheet-with-real-world-examples/#rules-of-hooks">Regras de hooks</a></li></ul><h2 id="fundamentos-do-react-1"><strong>Fundamentos do React</strong></h2><h3 id="elementos-jsx"><strong>Elementos JSX</strong></h3><p>As aplicações em React são estruturadas usando uma sintaxe chamada <strong><strong>JSX</strong></strong>. Esta é a sintaxe de um <strong><strong>elemento JSX</strong></strong> básico.</p><pre><code class="language-js">/* 
  O JSX nos permite escrever em uma sintaxe quase idêntica à do HTML simples.
  O resultado disso é que o JSX é uma ferramenta poderosa para estruturar nossas aplicações.
  O JSX usa todas as tags HTML válidas (ou seja, div/span, h1-h6, form/input, img etc.).
*/

&lt;div&gt;Alô, React!&lt;/div&gt;

/* 
  Observação: esse JSX não seria visível porque precisa ser renderizado por nossa aplicação usando ReactDOM.render()
*/</code></pre><p>O JSX é a maneira mais comum de estruturar aplicações em React, mas não é obrigatório para o React.</p><pre><code class="language-js">/* O JSX é uma maneira mais simples de usar a função React.createElement()
Em outras palavras, as duas linhas a seguir no React são iguais: */

&lt;div&gt;Alô, React!&lt;/div&gt;  // sintaxe do JSX

React.createElement('div', null, 'Alô, React!'); // sintaxe do createElement</code></pre><p>O JSX não é compreendido pelo navegador. Ele precisa ser compilado em JavaScript puro para que o navegador possa entender.</p><p>O compilador mais comumente usado para JSX é chamado Babel.</p><pre><code class="language-js">/* 
  Quando nosso projeto é criado para ser executado no navegador, nosso JSX será convertido pelo Babel em chamadas simples da função React.createElement(). 
  Disto...
*/
const greeting = &lt;div&gt;Alô React!&lt;/div&gt;;

/* ...para isto: */
"use strict";

const greeting = /*#__PURE__*/React.createElement("div", null, "Alô, React!");</code></pre><p>O JSX difere do HTML de várias maneiras importantes:</p><pre><code class="language-js">/* 
  Podemos escrever JSX como se fosse HTML simples, mas na verdade ele é feito usando funções JavaScript.
  Como o JSX é JavaScript, e não HTML, há algumas diferenças:

  1) Alguns atributos JSX têm nomes diferentes dos atributos HTML. Por quê? Porque algumas palavras de atributos são palavras reservadas em JavaScript, como 'class' (classe). Em vez de class, o JSX usa 'className'.

  Além disso, como o JSX é JavaScript, os atributos que consistem em várias palavras são escritos em camelcase:
*/

&lt;div id="header"&gt;
  &lt;h1 className="title"&gt;Alô, React!&lt;/h1&gt;
&lt;/div&gt;

/* 
  2) Os elementos JSX que consistem em apenas uma única tag (ou seja, elementos input, img, br) devem ser fechados com uma barra à direita para serem válidos (/): 
*/

&lt;input type="email" /&gt; // &lt;input type="email"&gt; é um erro de sintaxe

/* 
  3) Os elementos JSX que consistem em uma tag de abertura e de fechamento (ou seja, div, span, elemento de botão) devem ter ambas ou ser fechados com uma barra à direita. Como no item 2) acima, é um erro de sintaxe ter um elemento não encerrado. 
*/

&lt;button&gt;Clique aqui&lt;/button&gt; // somente &lt;button&gt; ou &lt;/button&gt; geram um erro de sintaxe
&lt;button /&gt; // vazio, mas também válido</code></pre><p>Estilos em linha podem ser adicionados aos elementos JSX usando o atributo <code>style</code>. Os estilos são atualizados em um objeto, e não em um conjunto de aspas duplas, como no HTML.</p><p>Observe que os nomes das propriedades de estilo também devem ser escritos em <em>camelcase</em>.</p><pre><code class="language-js">/* 
  As propriedades que aceitam valores de pixel (como largura, altura, preenchimento, margem etc.) podem usar números inteiros em vez de cadeias de caracteres.
  Por exemplo: fontSize: 22. Em vez de: fontSize: "22px"
*/
&lt;h1 style={{ color: 'blue', fontSize: 22, padding: '0.5em 1em' }}&gt;
  Alô, React!
&lt;/h1&gt;</code></pre><p>Os elementos JSX são expressões JavaScript e podem ser usados como tal. O JSX nos dá todo o poder do JavaScript diretamente em nossa interface de usuário.</p><pre><code class="language-js">/* 
  Os elementos JSX são expressões (resultam em um valor) e, portanto, podem ser atribuídos a variáveis JavaScript simples... 
*/
const greeting = &lt;div&gt;Alô, React!&lt;/div&gt;;

const isNewToReact = true;

// ... ou pode ser exibido condicionalmente
function sayGreeting() {
  if (isNewToReact) {
    // ... ou retornado de funções, etc.
    return greeting; // exibe: Alô, React!
  } else {
    return &lt;div&gt;Olá novamente, React&lt;/div&gt;;
  }
}</code></pre><p>O JSX nos permite inserir (ou incorporar) expressões JavaScript simples usando a sintaxe de chaves:</p><pre><code class="language-js">const year = 2021;

/* Podemos inserir valores JS primitivos (ou seja, strings, números, booleanos) entre chaves: {} */
const greeting = &lt;div&gt;Alô, React, em {year}&lt;/div&gt;;

/* Também podemos inserir expressões que resultam em um valor primitivo: */
const goodbye = &lt;div&gt;Adeus ano velho: {year - 1}&lt;/div&gt;

/* As expressões também podem ser usadas para atributos de elementos */
const className = 'title';
const title = &lt;h1 className={className}&gt;Meu título&lt;/h1&gt;

/* Observação: tentar inserir valores de objetos (por exemplo: objetos, arrays, maps) entre chaves resultará em um erro */</code></pre><p>O JSX nos permite aninhar elementos uns nos outros, como faríamos com o HTML.</p><pre><code class="language-js">/* 
  Para escrever JSX em várias linhas, coloque entre parênteses: ()
  As expressões JSX que abrangem várias linhas são chamadas de expressões multilinhas
*/

const greeting = (
  // div é o elemento pai
  &lt;div&gt;
    {/* h1 e p são elementos filhos */}
    &lt;h1&gt;Alô!&lt;/h1&gt;
    &lt;p&gt;Bem vindo ao React&lt;/p&gt;
  &lt;/div&gt;
);
/* 'pais' e 'filhos' são a forma como descrevemos os elementos JSX em relação
uns com os outros, como se estivéssemos falando de elementos HTML */</code></pre><p>Os comentários em JSX são escritos como comentários JavaScript de várias linhas, escritos entre chaves, como este:</p><pre><code class="language-js">const greeting = (
  &lt;div&gt;
    {/* Este é um comentário de uma única linha */}
  	&lt;h1&gt;Alô!&lt;/h1&gt;
    	&lt;p&gt;Bem vindo ao React&lt;/p&gt;
    {/* Este é 
    	um comentário
        de várias linhas */} 
  &lt;/div&gt;
);</code></pre><p>Todas as aplicações em React exigem três coisas:</p><ol><li><code>ReactDOM.render()</code>: usado para renderizar (exibir) nossa aplicação, montando-a em um elemento HTML</li><li>Um elemento JSX: chamado de "nó raiz", porque é a raiz da nossa aplicação. Em outras palavras, ao renderizá-lo, renderizará também todos os filhos dentro dele</li><li>Um elemento HTML (DOM): onde a aplicação é inserida em uma página HTML. O elemento geralmente é uma div com um id de valor "root", localizado em um arquivo index.html.</li></ol><pre><code class="language-js">// Os pacotes podem ser instalados localmente ou trazidos por meio de um link de um CDN (adicionado ao cabeçalho do documento HTML)
import React from "react";
import ReactDOM from "react-dom";

// O nó raiz (geralmente um componente) é mais frequentemente chamado de "App"
const App = &lt;h1&gt;Alô, React!&lt;/h1&gt;;

// ReactDOM.render(nó raiz, elemento HTML)
ReactDOM.render(App, document.getElementById("root"));</code></pre><h3 id="componentes-e-props"><strong>Componentes e <em>props</em></strong></h3><p>O JSX pode ser agrupado em funções individuais chamadas <strong><strong>componentes</strong></strong>.</p><p>Há dois tipos de componentes no React: <strong><strong>componentes de função</strong></strong> e <strong><strong>componentes de classe</strong></strong>.</p><p>Os nomes de componentes, sejam para componentes de função ou de classe, são capitalizados para distingui-los das funções JavaScript simples que não retornam JSX:</p><pre><code class="language-js">import React from "react";

/* 	
  Componente de função
  Observe o nome da função capitalizado: 'Header', e não 'header'
*/
function Header() {
  return &lt;h1&gt;Alô, React&lt;/h1&gt;;
}

// Os componentes de função que usam uma sintaxe de arrow function também são válidos
const Header = () =&gt; &lt;h1&gt;Alô, React&lt;/h1&gt;;

/* 
  Componente de classe
  Os componentes de classe têm mais boilerplate (observe a palavra-chave 'extends' e o método 'render'.)
*/
class Header extends React.Component {
  render() {
    return &lt;h1&gt;Alô, React&lt;/h1&gt;;
  }
}</code></pre><p>Os componentes, apesar de serem funções, não são chamados como funções JavaScript comuns. Eles são executados ao renderizá-los como faríamos com o JSX em nossa aplicação.</p><pre><code class="language-js">// Chamamos esse componente de função como uma função normal?

// Não, para executá-las e exibir o JSX que elas retornam...
const Header = () =&gt; &lt;h1&gt;Alô, React&lt;/h1&gt;;

// ...usamos como elementos JSX 'personalizados'.
ReactDOM.render(&lt;Header /&gt;, document.getElementById("root"));
// renderiza: &lt;h1&gt;Alô, React&lt;/h1&gt;</code></pre><p>A grande vantagem dos componentes é sua capacidade de serem reutilizados em todas as aplicações, sempre que necessário.</p><p>Como os componentes aproveitam o poder das funções JavaScript, podemos passar dados logicamente para eles, como faríamos ao passar um ou mais argumentos.</p><pre><code class="language-js">/* 
  Os componentes Header e Footer podem ser reutilizados em qualquer página da nossa aplicação.
  Os componentes eliminam a necessidade de reescrever o mesmo JSX várias vezes.
*/

// Componente IndexPage, visível na rota '/' de nosso aplicativo
function IndexPage() {
  return (
    &lt;div&gt;
      &lt;Header /&gt;
      &lt;Hero /&gt;
      &lt;Footer /&gt;
    &lt;/div&gt;
  );
}

// Componente AboutPage, visível na rota '/about'.
function AboutPage() {
  return (
    &lt;div&gt;
      &lt;Header /&gt;
      &lt;About /&gt;
      &lt;Testimonials /&gt;
      &lt;Footer /&gt;
    &lt;/div&gt;
  );
}</code></pre><p>Os dados passados aos componentes em JavaScript são chamados de <strong><strong>props</strong></strong>. As <em>props</em> são idênticas aos atributos dos elementos JSX/HTML simples, mas você pode acessar seus valores dentro do próprio componente.</p><p><em>Props</em> estão disponíveis nos parâmetros do componente para o qual são passadas. <em>Props</em> são sempre incluídas como propriedades de um objeto.</p><pre><code class="language-js">/* 
  O que fazemos se quisermos passar dados personalizados para o nosso componente a partir de um componente pai?
  Por exemplo, para exibir o nome do usuário no cabeçalho da aplicação.
*/

const username = "John";

/* 
  Para isso, adicionamos 'atributos' personalizados ao nosso componente, chamados props.
  Podemos adicionar muitos deles como quisermos e dar a eles nomes adequados aos dados que passamos.
Para passar o nome do usuário para o cabeçalho, usamos uma prop que chamamos apropriadamente de 'username'
*/
ReactDOM.render(
  &lt;Header username={username} /&gt;,
  document.getElementById("root")
);
// Chamamos essa prop de 'username', mas podemos usar qualquer identificador válido que daríamos, por exemplo, uma variável JavaScript

// props é o objeto que cada componente recebe como argumento
function Header(props) {
  // as props que criamos no componente (username)
  // se tornam propriedades no objeto props
  return &lt;h1&gt;Hello {props.username}&lt;/h1&gt;;
}</code></pre><p>As props nunca devem ser alteradas diretamente no componente filho.</p><p>Outra maneira de dizer isso é que as props nunca devem sofrer <strong><strong>mutação</strong></strong>, pois são um objeto JavaScript simples.</p><pre><code class="language-js">/* 
  Os componentes devem operar como funções 'puras'.
  Ou seja, para cada entrada, devemos poder esperar o mesmo resultado.
  Isso significa que não podemos alterar o objeto props, apenas ler a partir dele.
*/

// Não podemos modificar o objeto props :
function Header(props) {
  props.username = "Doug";

  return &lt;h1&gt;Hello {props.username}&lt;/h1&gt;;
}
/* 
  O que faríamos se quiséssemos modificar um valor de prop que é passado para o nosso componente?
  É nesse caso que usaríamos o state (consulte a seção useState).
*/</code></pre><p>A prop de <strong><strong>filhos</strong></strong> é útil se quisermos passar elementos/componentes como props para outros componentes.</p><pre><code class="language-js">// Podemos aceitar elementos (ou componentes) React como props?
// Sim, por meio de uma propriedade especial no objeto props chamada 'children'

function Layout(props) {
  return &lt;div className="container"&gt;{props.children}&lt;/div&gt;;
}

// A propriedade children é muito útil para quando você deseja que o mesmo
// componente (como um componente Layout) para envolver todos os outros componentes:
function IndexPage() {
  return (
    &lt;Layout&gt;
      &lt;Header /&gt;
      &lt;Hero /&gt;
      &lt;Footer /&gt;
    &lt;/Layout&gt;
  );
}

// página diferente, mas usa o mesmo componente Layout (graças à prop children)
function AboutPage() {
  return (
    &lt;Layout&gt;
      &lt;About /&gt;
      &lt;Footer /&gt;
    &lt;/Layout&gt;
  );
}</code></pre><p>Mais uma vez, como os componentes são expressões JavaScript, podemos usá-los em combinação com instruções <em>if-else</em> e <em>switch</em> para exibir conteúdo de modo condicional, como neste exemplo:</p><pre><code class="language-js">function Header() {
  const isAuthenticated = checkAuth();
    
  /* se o usuário estiver autenticado, mostrar a aplicação autenticada; caso contrário, a aplicação não autenticado */
  if (isAuthenticated) {
    return &lt;AuthenticatedApp /&gt;   
  } else {
    /* Como alternativa, podemos eliminar a seção else e fornecer um simples retorno, e a condicional funcionará da mesma maneira */
    return &lt;UnAuthenticatedApp /&gt;   
  }
}</code></pre><p>Para usar condições no JSX retornado de um componente, você pode usar o operador ternário ou o curto-circuito (operadores &amp;&amp; e ||).</p><pre><code class="language-js">function Header() {
  const isAuthenticated = checkAuth();

  return (
    &lt;nav&gt;
      {/* Se isAuth for verdadeiro, não mostrará nada. Se for falso, mostre Logo  */}
      {isAuthenticated || &lt;Logo /&gt;}
      {/* Se isAuth for verdadeiro, exibirá AuthenticatedApp. Se for falso, exibirá Login  */}
      {isAuthenticated ? &lt;AuthenticatedApp /&gt; : &lt;LoginScreen /&gt;}
      {/* Se isAuth for verdadeiro, exibirá o Footer. Se for falso, não mostrará nada */}
      {isAuthenticated &amp;&amp; &lt;Footer /&gt;}
    &lt;/nav&gt;
  );
}</code></pre><p><em><strong>F<strong>ragments</strong></strong> </em>são componentes especiais para exibir vários componentes sem adicionar um elemento extra ao DOM. Eles são ideais para a lógica condicional que tem vários componentes ou elementos adjacentes.</p><pre><code class="language-js">/*
  Podemos aprimorar a lógica do exemplo anterior.
  Se isAuthenticated for verdadeiro, como exibimos os componentes AuthenticatedApp e Footer?
*/
function Header() {
  const isAuthenticated = checkAuth();

  return (
    &lt;nav&gt;
      &lt;Logo /&gt;
      {/* 
        Podemos renderizar os dois componentes com um fragment. 
        Fragments são muito concisos: &lt;&gt; &lt;/&gt;
      */}
      {isAuthenticated ? (
        &lt;&gt;
          &lt;AuthenticatedApp /&gt;
          &lt;Footer /&gt;
        &lt;/&gt;
      ) : (
        &lt;Login /&gt;
      )}
    &lt;/nav&gt;
  );
}
/* 
  Observação: uma sintaxe alternativa para fragments é React.Fragment:
  &lt;React.Fragment&gt;
     &lt;AuthenticatedApp /&gt;
     &lt;Footer /&gt;
  &lt;/React.Fragment&gt;
*/</code></pre><h3 id="listas-e-chaves"><strong>Listas e chaves</strong></h3><p>Use a função <strong><strong>.map()</strong></strong> para converter listas de dados (<em>arrays</em>) em listas de elementos.</p><pre><code class="language-js">const people = ["John", "Bob", "Fred"];
const peopleList = people.map(person =&gt; &lt;p&gt;{person}&lt;/p&gt;);
</code></pre><p><code>.map()</code> pode ser usado para componentes, bem como para elementos JSX simples.</p><pre><code class="language-js">function App() {
  const people = ['John', 'Bob', 'Fred'];
  // pode interpolar a lista retornada de elementos em {}
  return (
    &lt;ul&gt;
      {/* estamos passando cada elemento do array como props para Person */}
      {people.map(person =&gt; &lt;Person name={person} /&gt;}
    &lt;/ul&gt;
  );
}

function Person({ name }) {
  // acessamos a propriedade 'name' diretamente usando a desestruturação de objetos
  return &lt;p&gt;This person's name is: {name}&lt;/p&gt;;
}</code></pre><p>Cada elemento do React em uma lista de elementos precisa de uma <strong><strong><em>key prop</em></strong></strong> especial. As <em>keys </em>são essenciais para que o React possa manter o controle de cada elemento que está sendo iterado com a função <code>.map()</code>.</p><p>O React usa <em>keys</em> (em português, chaves) para atualizar com desempenho elementos individuais quando seus dados são alterados (em vez de renderizar novamente a lista inteira).</p><p>As <em>keys </em>precisam ter valores únicos para que seja possível identificar cada uma delas de acordo com o valor da <em>key</em>.</p><pre><code class="language-js">function App() {
  const people = [
    { id: 'Ksy7py', name: 'John' },
    { id: '6eAdl9', name: 'Bob' },
    { id: '6eAdl9', name: 'Fred' },
  ];

  return (
    &lt;ul&gt;
      {/* as chaves precisam ser valores primitivos, de preferência uma string exclusiva, como um ID */}
      {people.map(person =&gt;
         &lt;Person key={person.id} name={person.name} /&gt;
      )}
    &lt;/ul&gt;
  );
}

// Se você não tiver alguns IDs em seu conjunto de dados que sejam valores únicos e primitivos, use o segundo parâmetro de .map() para obter o índice de cada elemento.

function App() {
  const people = ['John', 'Bob', 'Fred'];

  return (
    &lt;ul&gt;
      {/* usar o índice do elemento do array como chave */}
      {people.map((person, i) =&gt; &lt;Person key={i} name={person} /&gt;)}
    &lt;/ul&gt;
  );
}</code></pre><h3 id="ouvintes-de-eventos-e-tratamento-de-eventos">Ouvintes de eventos e tratamento de evento<strong>s</strong></h3><p>A escuta de eventos em elementos JSX em contraste com elementos HTML difere em alguns aspectos importantes.</p><p>Primeiro, você não pode ouvir eventos em componentes do React – somente em elementos JSX. Adicionar uma propriedade chamada <code>onClick</code>, por exemplo, a um componente do React seria apenas outra propriedade adicionada ao objeto <em>props</em>.</p><pre><code class="language-js">/* 
  A convenção para a maioria das funções de manipulador de eventos é prefixá-las com a palavra 'handle' e, em seguida, com a ação que elas executam (por exemplo, handleToggleTheme)
*/
function handleToggleTheme() {
  // código para alternar o tema da aplicação
}

/* Em HTML, onclick está todo em letras minúsculas, e o manipulador de eventos inclui um conjunto de parênteses após ser referenciado */
&lt;button onclick="handleToggleTheme()"&gt;
  Alterar o tema
&lt;/button&gt;

/* 
  Em JSX, onClick é camelcase, como os atributos / props.
  Também passamos uma referência à função com chaves.
*/
&lt;button onClick={handleToggleTheme}&gt;
  Alterar o tema
&lt;/button&gt;</code></pre><p>Os eventos do React mais importantes a serem conhecidos são <code>onClick</code>, <code>onChange</code> e <code>onSubmit</code>.</p><ul><li><code>onClick</code> lida com eventos de clique em elementos JSX (ou seja, em botões)</li><li><code>onChange</code> trata de eventos de teclado (ou seja, um usuário digitando em um campo de input ou textarea)</li><li><code>onSubmit</code> trata os envios de formulários do usuário</li></ul><pre><code class="language-js">function App() {
  function handleInputChange(event) {
    /* Ao passar a função para um manipulador de eventos, como onChange, obtemos acesso aos dados sobre o evento (um objeto) */
    const inputText = event.target.value; // texto digitado no input
    const inputName = event.target.name; // 'email' do atributo name
  }

  function handleClick(event) {
    /* O onClick normalmente não precisa de dados de eventos, mas também recebe dados de eventos que podemos usar */
    console.log('clicked!');
    const eventType = event.type; // "click"
    const eventTarget = event.target; // &lt;button&gt;Enviar&lt;/button&gt;
  }
    
  function handleSubmit(event) {
    /* 
     Quando pressionarmos o botão de retorno, o formulário será enviado, assim como quando um botão com type=“submit” for clicado.
     Chamamos event.preventDefault() para evitar que o comportamento padrão do formulário ocorra, que é enviar uma solicitação HTTP e recarregar a página.
    */
    event.preventDefault();
    const formElements = event.target.elements; // acessar todos os elementos do formulário
    const inputValue = event.target.elements.emailAddress.value; // acessar o valor do elemento de entrada com o id “emailAddress”
  }

  return (
    &lt;form onSubmit={handleSubmit}&gt;
      &lt;input id="emailAddress" type="email" name="email" onChange={handleInputChange} /&gt;
      &lt;button onClick={handleClick}&gt;Enviar&lt;/button&gt;
    &lt;/form&gt;
  );
}
</code></pre><h2 id="hooks-essenciais-do-react-1">Hooks essenciais do React</h2><h3 id="state-e-usestate"><strong><em>State</em> e useState</strong></h3><p>O hook <code>useState</code> nos fornece o <em>state</em> (em português, estado) em um componente de função. <strong><strong>O </strong><em>state</em></strong> nos permite acessar e atualizar determinados valores em nossos componentes ao longo do tempo.</p><p>O <em>state</em> do componente local é gerenciado pelo hook <code>useState</code> do React, que nos fornece uma variável de <em>state</em> e uma função que nos permite atualizá-la.</p><p>Quando chamamos <code>useState</code>, podemos dar ao nosso <em>state</em> um valor padrão, fornecendo-o como o primeiro argumento quando chamamos <code>useState</code>.</p><pre><code class="language-js">import React from 'react';

/* 
  Como você cria uma variável do state?
  Syntax: const [stateVariable] = React.useState(defaultValue);
*/
function App() {
  const [language] = React.useState('JavaScript');
  /* 
    Usamos a desestruturação do array para declarar a variável do state.
    Como qualquer variável, declaramos que podemos dar a ela o nome que quisermos (neste caso, 'language').
  */

  return &lt;div&gt;Estou aprendendo {language}&lt;/div&gt;;
}</code></pre><p>Observação: qualquer <em>hook</em> nesta seção é da biblioteca principal do React e pode ser importado individualmente.</p><pre><code class="language-js">import React, { useState } from "react";

function App() {
  const [language] = useState("javascript");

  return &lt;div&gt;Estou aprendendo {language}&lt;/div&gt;;
}</code></pre><p><code>useState</code> também nos fornece uma função 'setter' para atualizar o <em>state</em> depois que ele é criado.</p><pre><code class="language-js">function App() {
  /* 
   A função setter é sempre o segundo valor desestruturado.
   A convenção de nomenclatura da função setter deve ser prefixada com 'set'.
  */
  const [language, setLanguage] = React.useState("javascript");

  return (
    &lt;div&gt;
      &lt;button onClick={() =&gt; setLanguage("python")}&gt;
        Aprenda Python
      &lt;/button&gt;
      {/*  
        Por que usar uma arrow function em linha aqui em vez de chamá-la imediatamente assim: onClick={setterFn()}? 
        Se fosse assim, setLanguage seria chamado imediatamente e não quando o usuário clicasse no botão.
        */}
      &lt;p&gt;Agora estou aprendendo {language}&lt;/p&gt;
    &lt;/div&gt;
  );
}

/* 
 Observação: sempre que a função setter é chamada, o state é atualizado,
 e o componente da aplicação é renderizado novamente para exibir o novo state.
 Sempre que o state for atualizado, o componente será renderizado novamente.
*/</code></pre><p><code>useState</code> pode ser usado uma ou várias vezes em um único componente. Ele pode aceitar valores primitivos ou objetos para gerenciar o <em>state</em>.</p><pre><code class="language-js">function App() {
  const [language, setLanguage] = React.useState("python");
  const [yearsExperience, setYearsExperience] = React.useState(0);

  return (
    &lt;div&gt;
      &lt;button onClick={() =&gt; setLanguage("javascript")}&gt;
        Alterar a linguagem para JS
      &lt;/button&gt;
      &lt;input
        type="number"
        value={yearsExperience}
        onChange={event =&gt; setYearsExperience(event.target.value)}
      /&gt;
      &lt;p&gt;Agora estou aprendendo {language}&lt;/p&gt;
      &lt;p&gt;Eu tenho {yearsExperience} anos de experiência&lt;/p&gt;
    &lt;/div&gt;
  );
}</code></pre><p>Se o novo <em>state</em> depender do anterior, para garantir que a atualização seja feita de maneira confiável, podemos usar uma função dentro da função <em>setter</em> que nos forneça o <em>state</em> anterior correto.</p><pre><code class="language-js">/* Temos a opção de organizar o state usando o tipo de dado mais adequado, de acordo com os dados que estamos gerenciando */
function App() {
  const [developer, setDeveloper] = React.useState({
    language: "",
    yearsExperience: 0
  });

  function handleChangeYearsExperience(event) {
    const years = event.target.value;
    /* Devemos passar o objeto de state anterior que tínhamos com o operador spread para distribuir todas as suas propriedades */
    setDeveloper({ ...developer, yearsExperience: years });
  }

  return (
    &lt;div&gt;
      {/* Não há necessidade de obter o state anterior aqui; estamos substituindo o objeto inteiro */}
      &lt;button
        onClick={() =&gt;
          setDeveloper({
            language: "javascript",
            yearsExperience: 0
          })
        }
      &gt;
        Alterar a linguagem para JS
      &lt;/button&gt;
      {/* Também podemos passar uma referência para a função */}
      &lt;input
        type="number"
        value={developer.yearsExperience}
        onChange={handleChangeYearsExperience}
      /&gt;
      &lt;p&gt;Agora estou aprendendo {developer.language}&lt;/p&gt;
      &lt;p&gt;Eu tenho {developer.yearsExperience} anos de experiência&lt;/p&gt;
    &lt;/div&gt;
  );
}</code></pre><p>Se você estiver gerenciando vários valores primitivos, usar <code>o useState</code> várias vezes geralmente é melhor do que usá-lo uma vez com um objeto. Você não precisa se preocupar em esquecer de combinar o <em>state</em> antigo com o novo.</p><pre><code class="language-js">function App() {
  const [developer, setDeveloper] = React.useState({
    language: "",
    yearsExperience: 0,
    isEmployed: false
  });

  function handleToggleEmployment(event) {
    /* Obtemos o valor da variável do state anterior nos parâmetros.
       Podemos nomear 'prevState' como quisermos.
    */
    setDeveloper(prevState =&gt; {
      return { ...prevState, isEmployed: !prevState.isEmployed };
      // É essencial retornar o novo estado a partir dessa função
    });
  }

  return (
    &lt;button onClick={handleToggleEmployment}&gt;Alternar status de emprego&lt;/button&gt;
  );
}
</code></pre><h3 id="efeitos-colaterais-e-useeffect">Efeitos colaterais e <strong>useEffect</strong></h3><p><code>useEffect</code> nos permite executar efeitos colaterais em componentes de função. Então, o que são efeitos colaterais?</p><p><strong>E<strong>feitos colaterais</strong></strong> ocorrem quando precisamos entrar em contato com o mundo externo. Por exemplo, buscar dados de uma API ou trabalhar com o DOM.</p><p>São ações que podem alterar o <em>state</em> do nosso componente de modo imprevisível (causando 'efeitos colaterais').</p><p><code>useEffect</code> aceita uma função de <em>callback</em> (chamada de função de 'efeito') que, por padrão, será executada sempre que houver uma nova renderização.</p><p>Ela é executada quando nosso componente é montado, que é o momento certo para executar um efeito colateral no ciclo de vida do componente.</p><pre><code class="language-js">/* O que o nosso código faz? Escolhe uma cor do array de cores e a transforma em cor de fundo */
import React, { useState, useEffect } from 'react';

function App() {
  const [colorIndex, setColorIndex] = useState(0);
  const colors = ["blue", "green", "red", "orange"];

  /* 
    Estamos causando um 'efeito colateral', pois estamos trabalhando com uma API.
    Estamos trabalhando com o DOM, uma API do navegador fora do React.
  */
  useEffect(() =&gt; {
    document.body.style.backgroundColor = colors[colorIndex];
  });
  /* Sempre que o state é atualizado, a aplicação é renderizada novamente e o useEffect é executado */

  function handleChangeColor() {
    /* Esse código pode parecer complexo, mas tudo o que ele faz é ir para a próxima cor no array 'colors' e, se estiver na última cor, voltar ao início */
    const nextIndex = colorIndex + 1 === colors.length ? 0 : colorIndex + 1;
    setColorIndex(nextIndex);
  }

  return (
    &lt;button onClick={handleChangeColor}&gt;
      Alterar a cor do fundo
    &lt;/button&gt;
  );
}</code></pre><p>Para evitar a execução da chamada da <em>callback</em> do efeito após cada renderização, fornecemos um segundo argumento, um <em>array</em> vazio.</p><pre><code class="language-js">function App() {
  ...
  /* 
    Com um array vazio, nosso botão não funciona, não importa quantas vezes clicarmos nele... 
    A cor de fundo é definida apenas uma vez, quando o componente é montado pela primeira vez.
  */
  useEffect(() =&gt; {
    document.body.style.backgroundColor = colors[colorIndex];
  }, []);

  /* 
    Como evitar que a função de efeito seja executada a cada atualização de estado e, ainda assim, fazer com que ela funcione sempre que o botão for clicado?
  */

  return (
    &lt;button onClick={handleChangeIndex}&gt;
      Alterar a cor do fundo
    &lt;/button&gt;
  );
}</code></pre><p><code>useEffect</code> nos permite executar efeitos condicionalmente com o <em>array </em>de dependências.</p><p>Um <strong><em>array</em> <strong>de dependências</strong></strong> é o segundo argumento e, se qualquer um dos valores do <em>array </em>for alterado, a função de efeito será executada novamente.</p><pre><code class="language-js">function App() {
  const [colorIndex, setColorIndex] = React.useState(0);
  const colors = ["blue", "green", "red", "orange"];

  /* 
    Vamos adicionar colorIndex ao nosso array de dependências
    Quando o colorIndex for alterado, o useEffect executará a função de efeito novamente
  */
  useEffect(() =&gt; {
    document.body.style.backgroundColor = colors[colorIndex];
    /* 
      Quando usamos o useEffect, precisamos pensar em quais valores de state
      queremos que nosso efeito colateral seja sincronizado
    */
  }, [colorIndex]);

  function handleChangeIndex() {
    const next = colorIndex + 1 === colors.length ? 0 : colorIndex + 1;
    setColorIndex(next);
  }

  return (
    &lt;button onClick={handleChangeIndex}&gt;
      Alterar a cor do fundo
    &lt;/button&gt;
  );
}</code></pre><p><code>useEffect</code> nos permite cancelar a assinatura de determinados efeitos retornando uma função no final.</p><pre><code class="language-js">function MouseTracker() {
  const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });

  React.useEffect(() =&gt; {
    // .addEventListener() configura um ouvinte ativo...
    window.addEventListener("mousemove", handleMouseMove);

    /* ...Portanto, quando saímos desta página, ele precisa ser
       removido para parar de ouvir. Caso contrário, ele tentará definir o
       state em um componente que não existe (causando um erro)

     Cancelamos a inscrição de todas as inscrições/ouvintes com essa “função de limpeza”)
     */
    return () =&gt; {
      window.removeEventListener("mousemove", handleMouseMove);
    };
  }, []);

function handleMouseMove(event) {
   setMousePosition({
     x: event.pageX,
     y: event.pageY
   });
}

  return (
    &lt;div&gt;
      &lt;h1&gt;A posição atual do mouse é:&lt;/h1&gt;
      &lt;p&gt;
        X: {mousePosition.x}, Y: {mousePosition.y}
      &lt;/p&gt;
    &lt;/div&gt;
  );
}</code></pre><p><code>useEffect</code> é o <em>hook </em>a ser usado quando você quiser fazer uma solicitação HTTP (ou seja, uma solicitação GET quando o componente for montado).</p><p>Observe que o tratamento de <em>promises</em> com a sintaxe mais concisa async/await exige a criação de uma função separada. (Por quê? Porque a função de <em>callback</em> do efeito não pode ser assíncrona).</p><pre><code class="language-js">const endpoint = "https://api.github.com/users/reedbarger";

// Usando funções de callback .then() para resolver a promise
function App() {
  const [user, setUser] = React.useState(null);

  React.useEffect(() =&gt; {
    fetch(endpoint)
      .then(response =&gt; response.json())
      .then(data =&gt; setUser(data));
  }, []);
}

// Usando a sintaxe async/ await para resolver a promise:
function App() {
  const [user, setUser] = React.useState(null);
  // não é possível tornar assíncrona a função de callback useEffect
  React.useEffect(() =&gt; {
    getUser();
  }, []);

  // Devemos aplicar a palavra-chave async a uma função separada
  async function getUser() {
    const response = await fetch(endpoint);
    const data = await response.json();
    setUser(data);
  }
}
</code></pre><h3 id="refs-e-useref"><strong>Refs e useRef</strong></h3><p><strong><strong>Refs</strong></strong> são um atributo especial que está disponível em todos os componentes do React. Eles nos permitem criar uma referência a um determinado elemento/componente quando o componente é montado.</p><p>O <code>useRef</code> nos permite usar facilmente as <code>refs</code> do React. Chamamos useRef (na parte superior do componente) e anexamos o valor retornado ao atributo <code>ref</code> do elemento para fazer referência a ele.</p><p>Depois de criarmos uma referência, usamos a propriedade <code>current</code> para modificar (silenciar) as propriedades do elemento ou podemos chamar quaisquer métodos disponíveis nesse elemento (como <code>.focus()</code> para focalizar uma entrada).</p><pre><code class="language-js">function App() {
  const [query, setQuery] = React.useState("react hooks");
  /* Podemos passar um valor padrão para useRef.
     Não precisamos dele aqui, então passamos null para fazer referência a um objeto vazio
  */
  const searchInput = useRef(null);

  function handleClearSearch() {
    /* 
      .current faz referência ao elemento de entrada na montagem
      useRef pode armazenar basicamente qualquer valor em sua propriedade .current
    */
    searchInput.current.value = "";
    searchInput.current.focus();
  }

  return (
    &lt;form&gt;
      &lt;input
        type="text"
        onChange={event =&gt; setQuery(event.target.value)}
        ref={searchInput}
      /&gt;
      &lt;button type="submit"&gt;Buscar&lt;/button&gt;
      &lt;button type="button" onClick={handleClearSearch}&gt;
        Limpar
      &lt;/button&gt;
    &lt;/form&gt;
  );
}
</code></pre><h2 id="hooks-e-desempenho-1"><strong>Hooks e desempenho</strong></h2><h3 id="preven-o-de-novas-renderiza-es-e-react-memo"><strong>Prevenção de novas renderizações e React.memo</strong></h3><p><code>React.memo</code> é uma função que nos permite otimizar o modo como nossos componentes são renderizados.</p><p>Em particular, ela executa um processo chamado <strong><strong>memoização </strong></strong>que nos ajuda a evitar que nossos componentes sejam renderizados novamente quando não for necessário (consulte React.useMemo para obter uma definição mais completa de memoização).</p><p><code>O React.memo</code> ajuda mais a evitar que listas de componentes sejam renderizadas novamente quando seus componentes pai são renderizados novamente.</p><pre><code class="language-js">/* 
  Na aplicação a seguir, estamos mantendo o controle de nossas habilidades de programação. Podemos criar novas habilidades usando uma entrada, e elas são adicionadas à lista (mostrada no componente SkillList). Se clicarmos em uma habilidade, ela será excluída.
*/

function App() {
  const [skill, setSkill] = React.useState('')
  const [skills, setSkills] = React.useState([
    'HTML', 'CSS', 'JavaScript'
  ])

  function handleChangeInput(event) {
    setSkill(event.target.value);
  }

  function handleAddSkill() {
    setSkills(skills.concat(skill))
  }

  return (
    &lt;&gt;
      &lt;input onChange={handleChangeInput} /&gt;
      &lt;button onClick={handleAddSkill}&gt;Adicionar habilidade&lt;/button&gt;
      &lt;SkillList skills={skills} /&gt;
    &lt;/&gt;
  );
}

/* O problema, se você mesmo executar esse código, é que, quando digitamos no input, como o componente pai da SkillList (App) é renderizado novamente, devido à atualização do state a cada pressionamento de tecla, a SkillList é renderizada constantemente (conforme indicado pelo console.log) */

/* No entanto, quando envolvemos o componente SkillList no React.memo (que é uma função de ordem superior, o que significa que ele aceita uma função como argumento), ele não será mais renderizado desnecessariamente quando nosso componente pai o fizer. */
const SkillList = React.memo(({ skills }) =&gt; {
  console.log('renderizando novamente');
  return (
    &lt;ul&gt;
    {skills.map((skill, i) =&gt; &lt;li key={i}&gt;{skill}&lt;/li&gt;)}
    &lt;/ul&gt;
  )
})

export default App</code></pre><h3 id="fun-es-de-callback-e-usecallback"><strong>Funções de <em>callback</em> e useCallback</strong></h3><p><code>useCallback</code> é um <em>hook </em>usado para melhorar o desempenho do nosso componente. <strong>F<strong>un</strong>ções de</strong> <strong><em>c<strong>allback</strong></em><strong> </strong></strong>são os nomes das funções que são "chamadas de volta" em um componente pai.</p><p>O uso mais comum é ter um componente pai com uma variável de <em>state</em>, mas você deseja atualizar esse estado em um componente filho. O que você faz? Você passa uma função de <em>callback</em> para o filho a partir do pai. Isso nos permite atualizar o <em>state</em> no componente pai.</p><p><code>useCallback</code> funciona de maneira semelhante ao <code>React.memo</code>. Ele memoriza as funções de <em>callback</em>, para que não sejam recriadas a cada nova renderização. O uso correto do <code>useCallback</code> pode melhorar o desempenho da nossa aplicação.</p><pre><code class="language-js">/* Vamos manter exatamente a mesma aplicação acima com o React.memo, mas adicionar uma pequena funcionalidade. Vamos permitir a exclusão de uma habilidade quando clicarmos nela. Para fazer isso, precisamos filtrar o array de habilidades de acordo com a habilidade em que clicamos. Para isso, criamos a função handleRemoveSkill no App */

function App() {
  const [skill, setSkill] = React.useState('')
  const [skills, setSkills] = React.useState([
    'HTML', 'CSS', 'JavaScript'
  ])

  function handleChangeInput(event) {
    setSkill(event.target.value);
  }

  function handleAddSkill() {
    setSkills(skills.concat(skill))
  }

  function handleRemoveSkill(skill) {
    setSkills(skills.filter(s =&gt; s !== skill))
  }
    
  /* Em seguida, passamos handleRemoveSkill como uma prop ou, como se trata de uma função, como uma função de callback a ser usada na SkillList */
  return (
    &lt;&gt;
      &lt;input onChange={handleChangeInput} /&gt;
      &lt;button onClick={handleAddSkill}&gt;Adicionar habilidade&lt;/button&gt;
      &lt;SkillList skills={skills} handleRemoveSkill={handleRemoveSkill} /&gt;
    &lt;/&gt;
  );
}

/* Quando tentamos digitar a entrada novamente, vemos uma nova renderização no console toda vez que digitamos. Nossa memoização do React.memo está quebrada! 

O que está acontecendo é que a função de callback handleRemoveSkill está sendo recriada toda vez que a aplicação é renderizada, fazendo com que todos os filhos também sejam renderizados. Precisamos envolver handleRemoveSkill em useCallback e fazer com que ela seja recriada somente quando o valor da habilidade for alterado.

Para corrigir nossa aplicação, substitua handleRemoveSkill por:

const handleRemoveSkill = React.useCallback((skill) =&gt; {
  setSkills(skills.filter(s =&gt; s !== skill))
}, [skills])

Experimente você mesmo!
*/
const SkillList = React.memo(({ skills, handleRemoveSkill }) =&gt; {
  console.log('renderizando novamente');
  return (
    &lt;ul&gt;
    {skills.map(skill =&gt; &lt;li key={skill} onClick={() =&gt; handleRemoveSkill(skill)}&gt;{skill}&lt;/li&gt;)}
    &lt;/ul&gt;
  )
})


export default App</code></pre><h3 id="memoiza-o-e-usememo">Memoização e useMemo</h3><p><code>useMemo</code> é muito semelhante ao <code>useCallback</code> e serve para melhorar o desempenho. Em vez de ser para <em>callbacks</em>, no entanto, ele serve para armazenar os resultados de cálculos custosos.</p><p><code>useMemo</code> nos permite <strong><strong>memoizar</strong></strong> ou lembrar o resultado de cálculos custosos quando eles já foram feitos para determinadas entradas.</p><p>Memoização significa que, se um cálculo já foi feito antes com uma determinada entrada, não há necessidade de fazê-lo novamente, pois já temos o resultado armazenado dessa operação.</p><p><code>useMemo</code> retorna um valor do cálculo, que é então armazenado em uma variável.</p><pre><code class="language-js">/* Com base em nossa aplicação de habilidades, vamos adicionar um recurso para pesquisar nossas habilidades disponíveis por meio de uma entrada de pesquisa adicional. Podemos adicionar isso em um componente chamado SearchSkills (mostrado acima da nossa SkillList).
*/

function App() {
  const [skill, setSkill] = React.useState('')
  const [skills, setSkills] = React.useState([
    'HTML', 'CSS', 'JavaScript', ...milhares de outros itens
  ])

  function handleChangeInput(event) {
    setSkill(event.target.value);
  }

  function handleAddSkill() {
    setSkills(skills.concat(skill))
  }

  const handleRemoveSkill = React.useCallback((skill) =&gt; {
    setSkills(skills.filter(s =&gt; s !== skill))
  }, [skills])
   
  return (
    &lt;&gt;
      &lt;SearchSkills skills={skills} /&gt;
      &lt;input onChange={handleChangeInput} /&gt;
      &lt;button onClick={handleAddSkill}&gt;Adicionar habilidade&lt;/button&gt;
      &lt;SkillList skills={skills} handleRemoveSkill={handleRemoveSkill} /&gt;
    &lt;/&gt;
  );
}

/* Vamos imaginar que temos uma lista de milhares de habilidades que queremos pesquisar. Como podemos encontrar e mostrar de modo eficiente as habilidades que correspondem ao nosso termo de pesquisa à medida que o usuário digita? */
function SearchSkills() {
  const [searchTerm, setSearchTerm] = React.useState('');  
      
  /* Usamos o React.useMemo para memorizar (lembrar) o valor retornado de nossa operação de pesquisa e executá-lo somente quando o searchTerm for alterado */
  const searchResults = React.useMemo(() =&gt; {
    return skills.filter((s) =&gt; s.includes(searchTerm);
  }), [searchTerm]);
    
  function handleSearchInput(event) {
    setSearchTerm(event.target.value);
  }
    
  return (
    &lt;&gt;
    &lt;input onChange={handleSearchInput} /&gt;
    &lt;ul&gt;
      {searchResults.map((result, i) =&gt; &lt;li key={i}&gt;{result}&lt;/li&gt;
    &lt;/ul&gt;
    &lt;/&gt;
  );
}


export default App</code></pre><h2 id="hooks-avan-ados-no-react"><strong>Hooks </strong>avançados no<strong> React </strong></h2><h3 id="contexto-e-usecontext"><strong>Contexto e useContext</strong></h3><p>No React, queremos evitar o seguinte problema de criar várias <em>props</em> para passar dados para dois ou mais níveis abaixo de um componente principal.</p><pre><code class="language-js">/* 
  O React Context nos ajuda a evitar a criação de várias props duplicadas.
  Esse padrão também é chamado de perfuração de props.
*/

/* Nesta aplicação, queremos passar os dados do usuário para o componente Header, mas primeiro eles precisam passar por um componente Main que não os utiliza */
function App() {
  const [user] = React.useState({ name: "Fred" });

  return (
    // Primeira prop 'user'
    &lt;Main user={user} /&gt;
  );
}

const Main = ({ user }) =&gt; (
  &lt;&gt;
    {/* Segunda prop 'user' */}
    &lt;Header user={user} /&gt;
    &lt;div&gt;Conteúdo do Main...&lt;/div&gt;
  &lt;/&gt;
);

const Header = ({ user }) =&gt; &lt;header&gt;Bem vindo, {user.name}!&lt;/header&gt;;</code></pre><p>O contexto é útil para transmitir <em>props </em>em vários níveis de componentes filhos a partir de um componente pai.</p><pre><code class="language-js">/* 
  Aqui está o exemplo anterior reescrito com o Context.
  Primeiro, criamos o contexto, no qual podemos passar os valores padrão.
  Chamamos isso de "UserContext" porque estamos transmitindo dados do usuário
*/
const UserContext = React.createContext();

function App() {
  const [user] = React.useState({ name: "Fred" });

  return (
    {/* 
      Envolvemos o componente pai com a propriedade Provider.
      Passamos os dados pela árvore de componentes na propriedade value.
     */}
    &lt;UserContext.Provider value={user}&gt;
      &lt;Main /&gt;
    &lt;/UserContext.Provider&gt;
  );
}

const Main = () =&gt; (
  &lt;&gt;
    &lt;Header /&gt;
    &lt;div&gt;Conteúdo do app Main&lt;/div&gt;
  &lt;/&gt;
);

/* 
  Não podemos remover as duas propriedades 'user'. Em vez disso, podemos simplesmente usar a propriedade Consumer para consumir os dados onde precisamos deles
*/
const Header = () =&gt; (
    {/* Usamos um padrão chamado render props para obter acesso aos dados */}
    &lt;UserContext.Consumer&gt;
      {user =&gt; &lt;header&gt;Bem vindo, {user.name}!&lt;/header&gt;}
    &lt;/UserContext.Consumer&gt;
);</code></pre><p>O hook <code>useContext</code> nos permite consumir o contexto em qualquer componente de função que seja filho do provedor, em vez de usar o padrão de renderização das <em>props</em>.</p><pre><code class="language-js">function Header() {
  /* Passamos o objeto de contexto inteiro para consumi-lo e podemos remover as tags de Consumer */
  const user = React.useContext(UserContext);
    
  return &lt;header&gt;Bem vindo, {user.name}!&lt;/header&gt;;
};
</code></pre><h3 id="redutores-e-usereducer"><strong>Redutores e useReducer</strong></h3><p>Os redutores são funções simples e previsíveis (puras) que recebem um objeto de <em>state</em> anterior e um objeto de ação e retornam um novo objeto de <em>state</em>.</p><pre><code class="language-js">/* Esse redutor gerencia o state do usuário em nossa aplicação: */

function userReducer(state, action) {
  /* Os redutores geralmente usam um comando switch para atualizar o state de uma maneira ou de outra com base na propriedade de tipo da ação */
    
  switch (action.type) {
    /* Se action.type tiver a string 'LOGIN', obteremos dados do objeto payload na ação */
    case "LOGIN":
      return { 
        username: action.payload.username, 
        email: action.payload.email
        isAuth: true 
      };
    case "SIGNOUT":
      return { 
        username: "",
        email: "",
        isAuth: false 
      };
    default:
      /* Se nenhum caso corresponder à ação recebida, retorne ao state anterior */
      return state;
  }
}</code></pre><p>Redutores são um padrão poderoso para gerenciar <em>states</em>, usado na popular biblioteca de gerenciamento de state do Redux (comumente usada com o React).</p><p>Os redutores podem ser usados no React com o <em>hook</em> <code>useReducer</code> para gerenciar o <em>state</em> em toda a aplicação, em comparação com o useState (que é para o <em>state</em> do componente local).</p><p>O <code>useReducer</code> pode ser combinado com o <code>useContext</code> para gerenciar dados e transmiti-los facilmente entre os componentes.</p><p>Assim, <code>useReducer</code> + <code>useContext</code> pode ser um sistema completo de gerenciamento de <em>state</em> para nossas aplicações.</p><pre><code class="language-js">const initialState = { username: "", isAuth: false };

function reducer(state, action) {
  switch (action.type) {
    case "LOGIN":
      return { username: action.payload.username, isAuth: true };
    case "SIGNOUT":
      // também poderia se espalhar no initialState aqui
      return { username: "", isAuth: false };
    default:
      return state;
  }
}

function App() {
  // useReducer requer uma função redutora para ser usada e um initialState
  const [state, dispatch] = useReducer(reducer, initialState);
  // Obtemos o resultado atual do redutor em 'state'

  // usamos o dispatch para 'despachar' ações, para executar nosso redutor
  // com os dados de que ele precisa (o objeto de ação)
  function handleLogin() {
    dispatch({ type: "LOGIN", payload: { username: "Ted" } });
  }

  function handleSignout() {
    dispatch({ type: "SIGNOUT" });
  }

  return (
    &lt;&gt;
      Usuário atual: {state.username}, isAuthenticated: {state.isAuth}
      &lt;button onClick={handleLogin}&gt;Login&lt;/button&gt;
      &lt;button onClick={handleSignout}&gt;Signout&lt;/button&gt;
    &lt;/&gt;
  );
}</code></pre><h3 id="escrevendo-hooks-personalizados">Escrevendo <em>hooks </em>personalizados</h3><p>Os <em>hooks </em>foram criados para reutilizar facilmente um comportamento entre componentes, da mesma forma que os componentes foram criados para reutilizar a estrutura em nossa aplicação.</p><p>Os <em>hooks </em>nos permitem adicionar funcionalidades personalizadas às nossas aplicações que atendam às nossas necessidades e podem ser combinados com todos os <em>hooks </em>existentes que abordamos.</p><p>Os <em>hooks </em>também podem ser incluídos em bibliotecas de terceiros para o bem de todos os desenvolvedores do React. Há muitas bibliotecas React excelentes que fornecem <em>hooks </em>personalizados, como <code>@apollo/client</code>, <code>react-query</code>, <code>swr</code> e outras.</p><pre><code class="language-js">/* Aqui está um hook personalizado do React chamado useWindowSize que escrevi para calcular o tamanho da janela (largura e altura) de qualquer componente no qual ele é usado */

import React from "react";

export default function useWindowSize() {
  const isSSR = typeof window !== "undefined";
  const [windowSize, setWindowSize] = React.useState({
    width: isSSR ? 1200 : window.innerWidth,
    height: isSSR ? 800 : window.innerHeight,
  });

  function changeWindowSize() {
    setWindowSize({ width: window.innerWidth, height: window.innerHeight });
  }

  React.useEffect(() =&gt; {
    window.addEventListener("resize", changeWindowSize);

    return () =&gt; {
      window.removeEventListener("resize", changeWindowSize);
    };
  }, []);

  return windowSize;
}

/* Para usar o hook, basta importá-lo para onde for necessário, chamá-lo e usar a largura sempre que quisermos ocultar ou mostrar determinados elementos, como em um componente Header. */

// components/Header.js

import React from "react";
import useWindowSize from "../utils/useWindowSize";

function Header() {
  const { width } = useWindowSize();

  return (
    &lt;div&gt;
      {/* visível somente quando a janela for maior que 500px */}
      {width &gt; 500 &amp;&amp; (
        &lt;&gt;
         Maior que 500px!
        &lt;/&gt;
      )}
      {/* visível em qualquer tamanho de janela */}
	  &lt;p&gt;Estou sempre visível&lt;/p&gt;
    &lt;/div&gt;
  );
}</code></pre><h3 id="regras-dos-hooks"><strong>Regras dos hooks</strong></h3><p>Há duas regras essenciais para o uso de <em>hooks </em>do React que não podem ser violadas para que funcionem corretamente:</p><ul><li>Os <em>hooks </em>só podem ser usados em componentes de função (não em funções JavaScript simples ou componentes de classe)</li><li>Os <em>hooks </em>só podem ser chamados na parte superior dos componentes (não podem estar em condicionais, laços ou funções aninhadas)</li></ul><h2 id="conclus-o"><strong><strong><strong>Conclusão</strong></strong></strong></h2><p>Há outros conceitos interessantes que você pode aprender, mas se você se comprometer a aprender os conceitos abordados nesta ficha informativa, terá uma ótima compreensão das partes mais importantes e poderosas da biblioteca do React.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como criar seu próprio hook do React: um guia passo a passo ]]>
                </title>
                <description>
                    <![CDATA[ Os hooks do React são uma customização essencial que permite que você adicione funcionalidades exclusivas às suas aplicações React. Em vários casos, se você quer adicionar uma certa funcionalidade à sua aplicação, pode simplesmente adicionar uma biblioteca de terceiros que já existe para resolver o seu problema. Se tal biblioteca ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-criar-seu-proprio-hook-do-react-um-guia-passo-a-passo/</link>
                <guid isPermaLink="false">66ca838afc5d380414eff9b0</guid>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Gustavo Cavalieri ]]>
                </dc:creator>
                <pubDate>Mon, 23 Sep 2024 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2024/09/how-to-create-custom-react-hooks.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/how-to-create-react-hooks/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Build Your Own React Hooks: A Step-by-Step Guide</a>
      </p><p>Os <em>hooks</em> do React são uma customização essencial que permite que você adicione funcionalidades exclusivas às suas aplicações React.</p><p>Em vários casos, se você quer adicionar uma certa funcionalidade à sua aplicação, pode simplesmente adicionar uma biblioteca de terceiros que já existe para resolver o seu problema. Se tal biblioteca não existir, porém, o que fazer?</p><p>Como um desenvolvedor de React, é importante aprender os processos de criar <em>hooks</em> customizáveis para resolver problemas ou adicionar funcionalidades que faltam aos seus projetos.</p><p>Neste guia passo a passo, eu vou mostrar como criar os seus próprios <em>hooks</em> do React decompondo três <em>hooks</em> que fiz para as minhas aplicações e mostrando quais problemas eles foram criados para resolver.</p><h2 id="1-usecopytoclipboard">1. useCopyToClipboard</h2><p>Em uma versão anterior do meu site, <a href="https://www.freecodecamp.org/portuguese/news/p/641c40f4-2030-4bf3-bb94-c0983637c274/reedbarger.com">reedbarger.com</a>, eu permitia que usuários copiassem o código dos meus artigos com a ajuda de um pacote chamado <code>react-copy-to-clipboard</code>.</p><p>Quando um usuário passa o mouse sobre o trecho de código, clica no botão de copiar e o código é adicionado para a área de transferência, ele pode, então, colar e usar o código onde quiser.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/09/fnmmit9fvxb4lejz3dcm.gif" class="kg-image" alt="fnmmit9fvxb4lejz3dcm" width="1280" height="720" loading="lazy"></figure><p>Ao invés de usar uma biblioteca de terceiros, no entanto, eu queria recriar essa funcionalidade com o meu próprio <em>hook </em>do React. Como qualquer outro <em>hook</em> customizável que crio, eu os coloco em uma pasta dedicada, geralmente chamada <code>utils</code> ou <code>lib</code>, especificamente, para funções que posso reutilizar na minha aplicação.</p><p>Colocaremos esse <em>hook</em> em um arquivo chamado <code>useCopyToClipboard.js</code> e criaremos uma função com o mesmo nome.</p><p>Existem várias maneiras de se copiar um texto para a área de transferência de um usuário. Prefiro utilizar uma biblioteca para isso, chamada <code>copy-to-clipboard</code>, que torna o processo mais confiável.</p><p>Ela exporta uma função que chamaremos de <code>copy</code>.</p><pre><code class="language-jsx">// utils/useCopyToClipboard.js
import React from "react";
import copy from "copy-to-clipboard";

export default function useCopyToClipboard() {}
</code></pre><p>Em seguida, criaremos uma função que será utilizada para copiar qualquer texto que deve ser adicionado a área de transferência de um usuário. Chamaremos essa função de <code>handleCopy</code>.</p><h3 id="como-criar-a-fun-o-handlecopy"><strong>Como criar a função <code>handleCopy</code></strong></h3><p>Nessa função, primeiramente, precisamos nos assegurar de que ela aceitará apenas parâmetros do tipo String ou Number. Colocaremos uma declaração com <code>if-else</code>, que garantirá que o tipo é uma String ou um Number. Caso contrário, imprimiremos um erro no console, que avisará o usuário de que ele não pode copiar qualquer outro tipo.</p><pre><code class="language-jsx">import React from "react";
import copy from "copy-to-clipboard";

export default function useCopyToClipboard() {
  const [isCopied, setCopied] = React.useState(false);

  function handleCopy(text) {
    if (typeof text === "string" || typeof text == "number") {
      // pode copiar
    } else {
      // não pode copiar
      console.error(
        `Não é permitido copiar o tipo ${typeof text} para a área de transferência; deve ser uma String ou um Number.`
      );
    }
  }
}</code></pre><p>Em seguida, devemos converter o parâmetro <code>text</code> para String e passá-lo para a função <code>copy</code>. Depois, retornamos a função <code>handleCopy</code> dentro do <em>hook </em>para ser utilizada em qualquer lugar da nossa aplicação.</p><p>Normalmente, a função <code>handleCopy</code> será conectada a um evento <code>onClick</code> de um botão.</p><pre><code class="language-jsx">import React from "react";
import copy from "copy-to-clipboard";

export default function useCopyToClipboard() {
  function handleCopy(text) {
    if (typeof text === "string" || typeof text == "number") {
      copy(text.toString());
    } else {
      console.error(
        `Não é permitido copiar o tipo ${typeof text} para a área de transferência, deve ser uma String ou um Number.`
      );
    }
  }

  return handleCopy;
}</code></pre><p>Além disso, queremos algum <em>state</em> que represente se o texto foi copiado ou não. Para criar esse comportamento, chamaremos <code>useState</code> no início do nosso <em>hook</em> e criaremos uma variável de estado <code>isCopied</code>, onde o método de atribuição se chamará <code>setCopy</code>.</p><p>Inicialmente, esse valor será <code>false</code>. Se o texto é copiado com sucesso, alteraremos a variável <code>copy</code> para <code>true</code>. Caso contrário, a alteraremos para <code>false</code>.</p><p>Finalmente, fazemos o <em>hook </em>retornar <code>isCopied</code> e <code>handleCopy</code> utilizando um array.</p><pre><code class="language-jsx">import React from "react";
import copy from "copy-to-clipboard";

export default function useCopyToClipboard(resetInterval = null) {
  const [isCopied, setCopied] = React.useState(false);

  function handleCopy(text) {
    if (typeof text === "string" || typeof text == "number") {
      copy(text.toString());
      setCopied(true);
    } else {
      setCopied(false);
      console.error(
        `Não é permitido copiar o tipo ${typeof text} para a área de transferência, deve ser uma String ou um Number.`
      );
    }
  }

  return [isCopied, handleCopy];
}
</code></pre><h3 id="como-utilizar-o-hook-usecopytoclipboard">Como utilizar o hook useCopyToClipboard</h3><p>Agora, podemos utilizar <code>useCopyToClipboard</code> dentro de qualquer componente que desejarmos.</p><p>Nesse caso, vou utilizá-lo com um componente de botão de copiar, que receberá o trecho de código que deve ser copiado.</p><p>Para fazer isso funcionar, tudo que precisamos é adicionar um evento de <code>onClick</code> ao botão. Nos parâmetros do nosso componente, recebemos código que será copiado para a área de transferência. Quando o código é copiado, podemos mostrar um ícone diferente indicando que o código foi copiado com sucesso.</p><pre><code class="language-jsx">import React from "react";
import ClipboardIcon from "../svg/ClipboardIcon";
import SuccessIcon from "../svg/SuccessIcon";
import useCopyToClipboard from "../utils/useCopyToClipboard";

function CopyButton({ code }) {
  const [isCopied, handleCopy] = useCopyToClipboard();

  return (
    &lt;button onClick={() =&gt; handleCopy(code)}&gt;
      {isCopied ? &lt;SuccessIcon /&gt; : &lt;ClipboardIcon /&gt;}
    &lt;/button&gt;
  );
}
</code></pre><h3 id="como-adicionar-um-intervalo-de-reinicializa-o">Como adicionar um intervalo de reinicialização</h3><p>Existe uma melhoria que podemos adicionar no nosso código. Na versão atual, <code>isCopied</code> sempre será <code>true</code>, e sempre veremos o ícone de sucesso:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/09/pgpdz9f5xp7nr4twovsn.gif" class="kg-image" alt="pgpdz9f5xp7nr4twovsn" width="1280" height="720" loading="lazy"></figure><p>Se quisermos reinicializar o <em>state</em> do componente após alguns segundos, podemos passar um intervalo de tempo como parâmetro para <code>useCopyToClipboard</code>. Adicionaremos essa funcionalidade.</p><p>De volta ao nosso <em>hook</em>, podemos criar um parâmetro chamado <code>resetInterval</code>, que terá como valor padrão <code>null</code>, o que garantirá que o <em>state</em> não será reinicializado se nenhum argumento for passado para ele.</p><p>Adicionaremos também a função <code>useEffect</code> para implementar o seguinte comportamento: se o texto for copiado e tivermos um intervalo de reinicialização, alteraremos o valor de <code>isCopied</code> novamente para <code>false</code> após o intervalo utilizando a função <code>setTimeout</code>.</p><p>Além disso, precisamos remover esse comportamento se o nosso o componente que está utilizando o nosso <em>hook</em> de desmontar (<em>unmount</em>). Ou seja, no caso de não existir mais <em>state</em> ou componente para ser atualizado.</p><pre><code class="language-jsx">import React from "react";
import copy from "copy-to-clipboard";

export default function useCopyToClipboard(resetInterval = null) {
  const [isCopied, setCopied] = React.useState(false);

  const handleCopy = React.useCallback((text) =&gt; {
    if (typeof text === "string" || typeof text == "number") {
      copy(text.toString());
      setCopied(true);
    } else {
      setCopied(false);
      console.error(
        `Não é permitido copiar o tipo ${typeof text} para a área de transferência, deve ser uma String ou um Number.`
      );
    }
  }, []);

  React.useEffect(() =&gt; {
    let timeout;
    if (isCopied &amp;&amp; resetInterval) {
      timeout = setTimeout(() =&gt; setCopied(false), resetInterval);
    }
    return () =&gt; {
      clearTimeout(timeout);
    };
  }, [isCopied, resetInterval]);

  return [isCopied, handleCopy];
}
</code></pre><p>Finalmente, a última melhoria que podemos fazer é envolver <code>handleCopy</code> em um <em>hook</em> <code>useCallback</code> para garantir que a função não seja recriada todas as vezes em que a tela for renderizada novamente.</p><h3 id="resultado">Resultado</h3><p>Com isso, temos o nosso <em>hook </em>que permite que o <em>state</em> seja reinicializado após um intervalo de tempo. Se passarmos um valor de tempo, veremos o resultado abaixo.</p><pre><code class="language-jsx">import React from "react";
import ClipboardIcon from "../svg/ClipboardIcon";
import SuccessIcon from "../svg/SuccessIcon";
import useCopyToClipboard from "../utils/useCopyToClipboard";

function CopyButton({ code }) {
  // isCopied é reinicializada após 3 segundos
  const [isCopied, handleCopy] = useCopyToClipboard(3000);

  return (
    &lt;button onClick={() =&gt; handleCopy(code)}&gt;
      {isCopied ? &lt;SuccessIcon /&gt; : &lt;ClipboardIcon /&gt;}
    &lt;/button&gt;
  );
}
</code></pre><h2 id="2-hook-usepagebottom">2. hook usePageBottom </h2><p>Em aplicações do React, muitas vezes, é importante saber quando o usuário rolou até o final da página.</p><p>Em aplicações que possuem "rolagem infinita", como o Instagram, por exemplo, quando o usuário chega no fim da página, a aplicação busca mais postagens.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/09/4dav187wpkl46skhhjgh.gif" class="kg-image" alt="4dav187wpkl46skhhjgh" width="1280" height="720" loading="lazy"></figure><p>Veremos como criar um <em>hook</em> <code>usePageBottom</code> para casos em que precisamos implementar uma página de rolagem infinita.</p><p>Começaremos criando um arquivo, <code>usePageBottom.js</code> na nossa pasta <code>utils</code> e adicionaremos uma função (<em>hook</em>) com o mesmo nome:</p><pre><code class="language-js">// utils/usePageBottom.js
import React from "react";

export default function usePageBottom() {}

</code></pre><p>Em seguida, precisamos calcular quando o usuário chega no final da página. Podemos determinar essa informação através do objeto <code>window</code>. Para acessar esse objeto, precisamos nos certificar de que o <em>hook </em>é chamado de um componente já montado (<em>isMounted</em>). Então, utilizaremos a função <code>useEffect</code> com um <em>array </em>vazio.</p><pre><code class="language-js">// utils/usePageBottom.js
import React from "react";

export default function usePageBottom() {
  React.useEffect(() =&gt; {}, []);
}

</code></pre><p>O usuário terá atingido o final da página quando o valor de <code>window.innerHeight</code> somado com <code>document.scrollTop</code> é igual ao valor de <code>document.offsetHeight</code>. Se esses dois valores são iguais, o resultado será <code>true</code> e o usuário terá atingido o final da página.</p><pre><code class="language-js">// utils/usePageBottom.js
import React from "react";

export default function usePageBottom() {
  React.useEffect(() =&gt; {
    window.innerHeight + document.documentElement.scrollTop === 
    document.documentElement.offsetHeight;
  }, []);
}

</code></pre><p>Salvaremos o resultado dessa expressão em uma variável <code>isBottom</code>, e atualizaremos uma variável de estado chamada <code>bottom</code>, que depois será retornada pelo nosso <em>hook</em>.</p><pre><code class="language-js">// utils/usePageBottom.js
import React from "react";

export default function usePageBottom() {
  const [bottom, setBottom] = React.useState(false);

  React.useEffect(() =&gt; {
    const isBottom =
      window.innerHeight + document.documentElement.scrollTop ===
      document.documentElement.offsetHeight;
    setBottom(isButton);
  }, []);

  return bottom;
}

</code></pre><p>Nosso código atual, no entanto, isso não funcionará. Por quê?</p><p>O problema está no fato que temos que calcular <code>isBottom</code> toda vez que o usuário está rolando a página. Por isso, precisamos receber eventos de rolagem da página utilizando <code>window.addEventListener</code>. Podemos criar uma função local que será chamada toda vez que o usuário rolar a página – a chamaremos de <code>handleScroll</code>.</p><pre><code class="language-js">// utils/usePageBottom.js
import React from "react";

export default function usePageBottom() {
  const [bottom, setBottom] = React.useState(false);

  React.useEffect(() =&gt; {
    function handleScroll() {
      const isBottom =
        window.innerHeight + document.documentElement.scrollTop 
        === document.documentElement.offsetHeight;
      setBottom(isButton);
    }
    window.addEventListener("scroll", handleScroll);
  }, []);

  return bottom;
}

</code></pre><p>Finalmente, como temos um "<em>event listener</em>" que atualizará o <em>state</em>, precisamos tratar o caso de o usuário sair da página e o nosso componente ser removido. Precisamos remover esse "<em>event listener</em>" que adicionamos para evitar que uma variável de estado que não existe mais seja alterada.</p><p>Podemos fazer isso retornando a função <code>window.removeEventListener</code>, onde passamos uma referência para a função <code>handleScroll</code>. Agora, tudo certo!</p><pre><code class="language-js">// utils/usePageBottom.js
import React from "react";

export default function usePageBottom() {
  const [bottom, setBottom] = React.useState(false);

  React.useEffect(() =&gt; {
    function handleScroll() {
      const isBottom =
        window.innerHeight + document.documentElement.scrollTop 
        === document.documentElement.offsetHeight;
      setBottom(isButton);
    }
    window.addEventListener("scroll", handleScroll);
    return () =&gt; {
      window.removeEventListener("scroll", handleScroll);
    };
  }, []);

  return bottom;
}

</code></pre><p>Podemos simplesmente chamar esse código em qualquer função em que queremos saber se o final da página foi atingido ou não.</p><p>Em um dos meus sites do Gatsby, eu tenho um cabeçalho. Conforme diminuo o tamanho da página, eu quero mostrar menos links para o usuário.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/09/kxbnn3jmwjarkc8zrpbm.gif" class="kg-image" alt="kxbnn3jmwjarkc8zrpbm" width="1280" height="720" loading="lazy"></figure><p>Para fazermos isso, podemos utilizar uma Media Query (CSS) ou podemos utilizar um <em>hook</em> do React para nos retornar o tamanho da página e exibir ou esconder os links no código JSX.</p><p>Anteriormente, eu estava utilizando um <em>hook</em> de uma biblioteca chamada <code>react-use</code>. Ao invés de utilizar uma biblioteca de terceiros, eu decidi criar meu próprio <em>hook</em> para retornar as dimensões da página, tanto largura quanto altura. Chamei esse <em>hook</em> de <code>useWindowSize</code>.</p><h3 id="como-criar-o-hook">Como criar o <em>hook</em></h3><p>Primeiramente, criaremos um arquivo <code>.js</code> na nossa pasta <code>utils</code>. Vamos chamá-lo de <code>useWindowSize</code>. Importaremos o React (para utilizar <em>hooks</em>) e exportaremos o <em>hook</em> atual.<br></p><pre><code class="language-js">// utils/useWindowSize.js

import React from "react";

export default function useWindowSize() {}

</code></pre><p>Como estou usando esse <em>hook </em>em um site do Gatsby.js, que é renderizado no servidor, eu preciso obter o tamanho da janela. Porém, talvez não tenhamos acesso ao tamanho da janela, pois estamos renderizando a página no servidor.</p><p>Para ter certeza de que não estamos no servidor, podemos verificar se o tipo de <code>window</code> não é igual a <code>undefined</code>.</p><p>Nesse caso, podemos retornar uma largura e altura para um navegador padrão. Retornaremos 1200 e 800 em um objeto.</p><pre><code class="language-js">// utils/useWindowSize.js

import React from "react";

export default function useWindowSize() {
  if (typeof window !== "undefined") {
    return { width: 1200, height: 800 };
  }
}

</code></pre><h3 id="como-obter-a-largura-e-altura-da-janela">Como obter a largura e altura da janela</h3><p>Quando estamos no <em>client</em> (navegador) e podemos utilizar a janela (<em>window</em>), temos a opção de usar o <em>hook</em> <code>useEffect</code> para interagir com a janela. Incluiremos um array vazio de dependências para ter certeza que o nosso <em>hook</em> é chamado apenas quando o componente pai está montado (<em>mounted</em>).</p><p>Para descobrir a largura e altura da janela, podemos adicionar um <em>event listener</em> para escutar por eventos do tipo <code>resize</code>. Toda vez que o tamanho da janela mudar, podemos atualizar uma parte do <em>state</em> (criado com <code>useState</code>), que chamaremos de <code>windowSize</code>, chamaremos o método de atualização de <code>setWindowSize</code>.<br></p><pre><code class="language-js">// utils/useWindowSize.js

import React from "react";

export default function useWindowSize() {
  if (typeof window !== "undefined") {
    return { width: 1200, height: 800 };
  }

  const [windowSize, setWindowSize] = React.useState();

  React.useEffect(() =&gt; {
    window.addEventListener("resize", () =&gt; {
      setWindowSize({ width: window.innerWidth, height: window.innerHeight });
    });
  }, []);
}

</code></pre><p>Quando a janela é redimensionada, o nosso <em>event listener</em> será chamado e o <em>state</em> de <code>windowSize</code> será atualizado com as novas dimensões. Para realizar isso, atualizamos a largura para <code>window.innerWidth</code> e a altura para <code>window.innerHeight</code>.</p><h3 id="como-adicionar-suporte-a-server-side-rendering">Como adicionar suporte a <em>Server Side Rendering</em></h3><p>No entanto, o nosso código atual não funcionará. Isso acontece porque existe uma regra dos <em>hooks</em> que os impedem de serem chamados condicionalmente. Como resultado, não podemos ter uma condicional nos métodos <code>useState</code> ou <code>useEffect</code> antes de eles serem chamados.</p><p>Então, para contornar esse problema, definiremos o valor inicial de <code>useState</code> condicionalmente. Criaremos uma variável chamada <code>isSSR</code>, que ficará responsável por verificar se a janela não é igual a uma string <code>undefined</code>.</p><p>Depois, utilizaremos um ternário para definir a largura e altura e checando primeiramente se estamos no servidor ou no navegador. Se estivermos no servidor, usaremos um valor padrão. Caso contrário, usaremos <code>window.innerWidth</code> e <code>window.innerHeight</code>.</p><pre><code class="language-js">// utils/useWindowSize.js

import React from "react";

export default function useWindowSize() {
  // if (typeof window !== "undefined") {
  // return { width: 1200, height: 800 };
  // }
  const isSSR = typeof window !== "undefined";
  const [windowSize, setWindowSize] = React.useState({
    width: isSSR ? 1200 : window.innerWidth,
    height: isSSR ? 800 : window.innerHeight,
  });

  React.useEffect(() =&gt; {
    window.addEventListener("resize", () =&gt; {
      setWindowSize({ width: window.innerWidth, height: window.innerHeight });
    });
  }, []);
}

</code></pre><p>Finalmente, precisamos pensar em como os nossos componentes desmontarão (<em>unmount</em>). O que precisamos fazer? É necessária a remoção do <em>listener</em> de redimensionamento.</p><h3 id="como-remover-o-event-listener-de-redimensionamento">Como remover o <em>event listener</em> de redimensionamento</h3><p>Podemos fazer isso retornando uma função no método <code>useEffect</code>. Removeremos o <em>listener</em> com <code>window.removeEventListener</code>.</p><pre><code class="language-js">// utils/useWindowSize.js

import React from "react";

export default function useWindowSize() {
  // if (typeof window !== "undefined") {
  // return { width: 1200, height: 800 };
  // }
  const isSSR = typeof window !== "undefined";
  const [windowSize, setWindowSize] = React.useState({
    width: isSSR ? 1200 : window.innerWidth,
    height: isSSR ? 800 : window.innerHeight,
  });

  React.useEffect(() =&gt; {
    window.addEventListener("resize", () =&gt; {
      setWindowSize({ width: window.innerWidth, height: window.innerHeight });
    });

    return () =&gt; {
      window.removeEventListener("resize", () =&gt; {
        setWindowSize({ width: window.innerWidth, height: window.innerHeight });
      });
    };
  }, []);
}

</code></pre><p>Precisamos, contudo, de uma referência para a mesma função e não de dois métodos diferentes como temos aqui. Para fazer isso, criaremos uma função de <em>callback</em> para os dois <em>listeners</em>, chamada <code>changeWindowSize</code>.</p><p>Para encerrar, no final do <em>hook</em>, retornaremos o <em>state</em> de <code>windowSize</code>.</p><pre><code class="language-js">// utils/useWindowSize.js

import React from "react";

export default function useWindowSize() {
  const isSSR = typeof window !== "undefined";
  const [windowSize, setWindowSize] = React.useState({
    width: isSSR ? 1200 : window.innerWidth,
    height: isSSR ? 800 : window.innerHeight,
  });

  function changeWindowSize() {
    setWindowSize({ width: window.innerWidth, height: window.innerHeight });
  }

  React.useEffect(() =&gt; {
    window.addEventListener("resize", changeWindowSize);

    return () =&gt; {
      window.removeEventListener("resize", changeWindowSize);
    };
  }, []);

  return windowSize;
}

</code></pre><h3 id="resultado-1">Resultado</h3><p>Para utilizar o <em>hook</em>, precisamos importá-lo onde ele é requerido, chamá-lo e utilizar a largura da janela retornada quando queremos esconder ou mostrar certos elementos na tela.</p><p>No exemplo abaixo, utilizaremos 500px como a nossa condição. Aqui, queremos esconder todos os links e mostrar apenas o botão "<em>Join Now</em>":</p><pre><code class="language-jsx">// components/StickyHeader.js

import React from "react";
import useWindowSize from "../utils/useWindowSize";

function StickyHeader() {
  const { width } = useWindowSize();

  return (
    &lt;div&gt;
      {/* visible only when window greater than 500px */}
      {width &gt; 500 &amp;&amp; (
        &lt;&gt;
          &lt;div onClick={onTestimonialsClick} role="button"&gt;
            &lt;span&gt;Testimonials&lt;/span&gt;
          &lt;/div&gt;
          &lt;div onClick={onPriceClick} role="button"&gt;
            &lt;span&gt;Price&lt;/span&gt;
          &lt;/div&gt;
          &lt;div&gt;
            &lt;span onClick={onQuestionClick} role="button"&gt;
              Question?
            &lt;/span&gt;
          &lt;/div&gt;
        &lt;/&gt;
      )}
      {/* visible at any window size */}
      &lt;div&gt;
        &lt;span className="primary-button" onClick={onPriceClick} role="button"&gt;
          Join Now
        &lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  );
}

</code></pre><p>Esse <em>hook </em>funcionará em qualquer aplicação do React renderizada no servidor, como as que usam Gatsby e Next.js.</p><h2 id="3-hook-usedevicedetect">3. hook useDeviceDetect</h2><p>Estou criando uma <em>landing page</em> para um curso e há um comportamento muito estranho quando a página é acessada por dispositivos móveis. Em computadores de mesa, está tudo certo.</p><p>Quando uso um dispositivo móvel, porém, tudo parece fora de lugar.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/09/n69a3h184fhniah3g1z8.gif" class="kg-image" alt="n69a3h184fhniah3g1z8" width="1280" height="720" loading="lazy"></figure><p>Descobri que o problema está relacionado com uma biblioteca chamada <code>react-device-detect</code>, que eu estava utilizando para detectar se os usuários acessavam o site de um dispositivo móvel ou não. Em caso afirmativo, o cabeçalho da página deve ser escondido.</p><pre><code class="language-jsx">// templates/course.js
import React from "react";
import { isMobile } from "react-device-detect";

function Course() {
  return (
    &lt;&gt;
      &lt;SEO /&gt;
      {!isMobile &amp;&amp; &lt;StickyHeader {...courseData} /&gt;}
      {/* more components... */}
    &lt;/&gt;
  );
}

</code></pre><p>O problema é que essa biblioteca não oferece suporte para renderização no servidor (em inglês, <em>server-side rendering</em>), que é o que o Gatsby usa por padrão. Então, precisei criar a minha própria solução para identificar quando o usuário acessa o site de um dispositivo móvel. Para isso, eu decidi criar um <em>hook</em> customizável chamado <code>useDeviceDetect</code>.</p><h3 id="como-criei-o-hook">Como criei o <em>hook</em></h3><p>Criei um arquivo separado para esse <em>hook </em>na pasta <code>utils</code>, chamado <code>useDeviceDetect.js</code>. Como <em>hooks </em>são simples funções do JavaScript que podem ser reaproveitadas, eu criei uma função chamada <code>useDeviceDetect</code> e importei as bibliotecas do React.</p><pre><code class="language-jsx">// utils/useDeviceDetect.js
import React from "react";

export default function useDeviceDetect() {}

</code></pre><h3 id="como-descobrir-o-user-agent-atrav-s-da-window">Como descobrir o <em>User Agent</em> através da <code>window</code></h3><p>Um jeito de descobrir informações sobre o dispositivo do usuário é através da propriedade <code>userAgent</code> (que está no objeto <code>navigator</code>, dentro de <code>window</code>).</p><p>Como interagir com a API <code>window</code> pode ser considerado um efeito colateral, precisamos acessar a propriedade "<em>user agent</em>" dentro do <em>hook </em><code>useEffect</code>.</p><pre><code class="language-jsx">// utils/useDeviceDetect.js
import React from "react";

export default function useDeviceDetect() {
  React.useEffect(() =&gt; {
    console.log(`Dispositivo do usuário: ${window.navigator.userAgent}`);
    // também pode ser escrito como 'navigator.userAgent'
  }, []);
}

</code></pre><p>Quando o componente for montado (<em>mounted</em>), podemos usar <code>typeof navigator</code> para determinar se estamos no navegador ou no servidor. Se estivermos no servidor, não teremos acesso ao <code>window</code>. Nesse caso, <code>typeof navigator</code> será igual à String <code>undefined</code>. Caso contrário, estamos no <em>client</em> e teremos acesso à propriedade "<em>user agent</em>".</p><p>Podemos expressar a lógica acima utilizando um ternário para obter a propriedade <code>userAgent</code>.</p><pre><code class="language-jsx">// utils/useDeviceDetect.js
import React from "react";

export default function useDeviceDetect() {
  React.useEffect(() =&gt; {
    const userAgent =
      typeof navigator === "undefined" ? "" : navigator.userAgent;
  }, []);
}

</code></pre><h3 id="como-checar-se-useragent-um-dispositivo-m-vel">Como checar se userAgent é um dispositivo móvel</h3><p><code>userAgent</code> é uma String que terá um dos valores abaixo caso o usuário esteja em um dispositivo móvel:</p><p>Android, BlackBerry, iPhone, iPad, iPod, Opera Mini, IEMobile, ou WPDesktop.</p><p>Tudo que precisamos fazer é utilizar a propriedade <code>userAgent</code> e o método <code>.match()</code> com uma expressão regular para checar se o valor é alguma das opções acima. Guardaremos o resultado em uma variável local chamada <code>mobile</code>.</p><p>Armazenaremos esse resultado no estado utilizando o <em>hook </em><code>useState</code>, que terá o valor inicial de <code>false</code>. Para isso, criamos a variável de estado <code>isMobile</code> e o método de atribuição <code>setMobile</code>.</p><pre><code class="language-jsx">// utils/useDeviceDetect.js
import React from "react";

export default function useDeviceDetect() {
  const [isMobile, setMobile] = React.useState(false);

  React.useEffect(() =&gt; {
    const userAgent =
      typeof window.navigator === "undefined" ? "" : navigator.userAgent;
    const mobile = Boolean(
      userAgent.match(
        /Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile|WPDesktop/i
      )
    );
    setMobile(mobile);
  }, []);
}

</code></pre><p>Então, quando definirmos o valor de <code>mobile</code>, vamos guardá-lo no <em>state</em>. Finalmente, retornaremos um objeto no caso de precisarmos adicionar novas informações e funcionalidades à esse <em>hook</em>.</p><p>No objeto de retorno, adicionaremos <code>isMobile</code> como uma propriedade e seu valor.</p><pre><code class="language-jsx">// utils/useDeviceDetect.js
import React from "react";

export default function useDeviceDetect() {
  const [isMobile, setMobile] = React.useState(false);

  React.useEffect(() =&gt; {
    const userAgent =
      typeof window.navigator === "undefined" ? "" : navigator.userAgent;
    const mobile = Boolean(
      userAgent.match(
        /Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile|WPDesktop/i
      )
    );
    setMobile(mobile);
  }, []);

  return { isMobile };
}

</code></pre><h3 id="resultado-2">Resultado</h3><p>De volta a nossa <em>landing page</em>, podemos executar o <em>hook</em> e utilizar o valor da propriedade <code>isMobile</code> onde quisermos.</p><pre><code class="language-jsx">// templates/course.js
import React from "react";
import useDeviceDetect from "../utils/useDeviceDetect";

function Course() {
  const { isMobile } = useDeviceDetect();

  return (
    &lt;&gt;
      &lt;SEO /&gt;
      {!isMobile &amp;&amp; &lt;StickyHeader {...courseData} /&gt;}
      {/* more components... */}
    &lt;/&gt;
  );
}

</code></pre><h2 id="conclus-o">Conclusão</h2><p>Como eu tentei demonstrar nos exemplos acima, os <em>hooks </em>do React podem nos fornecer as ferramentas necessárias para consertar os problemas quando bibliotecas externas falharem.</p><p>Espero que este guia tenha dado a você uma ideia melhor de como criar os seus próprios <em>hooks</em> em React. Fique à vontade para usar qualquer um dos <em>hooks </em>acima nos seus projetos ou como inspiração para criar outros <em>hooks</em>.</p><h2 id="torne-se-um-desenvolvedor-de-react-profissional">Torne-se um desenvolvedor de React profissional</h2><p>React é difícil. Você não precisa aprendê-lo sozinho.</p><p>Coloquei tudo o que sei sobre React em um único curso, para ajudar você a alcançar seus objetivos em tempo recorde:</p><p>Apresento a vocês: <a href="https://www.thereactbootcamp.com/"><strong>The React Bootcamp</strong></a> (em inglês)</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/09/react-bootcamp-cta-alt-1.png" class="kg-image" alt="react-bootcamp-cta-alt-1" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/09/react-bootcamp-cta-alt-1.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/09/react-bootcamp-cta-alt-1.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/09/react-bootcamp-cta-alt-1.png 1105w" sizes="(min-width: 720px) 720px" width="1105" height="394" loading="lazy"></figure><p><strong>É o curso que eu gostaria de ter feito quando comecei a aprender React.</strong></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como construir um menu acordeão em React a partir do zero – sem necessidade de bibliotecas externas ]]>
                </title>
                <description>
                    <![CDATA[ > Tradução em português europeu Existem várias maneiras de se utilizar menus acordeão, tais como exibir uma lista de FAQs (Perguntas frequentes, em português), exibir vários menus e submenus, exibir as localizações de uma empresa em particular, e assim adiante. Neste artigo, verás como criar um menu acordeão em React ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-construir-um-menu-acordeao-em-react-a-partir-do-zero-sem-necessidade-de-bibliotecas-externashow-to-build-an-accordion-menu-in-react-from-scratch-no-external-libraries-required/</link>
                <guid isPermaLink="false">6696773fa696970403cc04b8</guid>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Afonso Branco ]]>
                </dc:creator>
                <pubDate>Tue, 03 Sep 2024 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2024/09/604df0d628094f59be2558d6.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/build-accordion-menu-in-react-without-external-libraries/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Build an Accordion Menu in React from Scratch – No External Libraries Required</a>
      </p><blockquote>Tradução em português europeu</blockquote><p>Existem várias maneiras de se utilizar menus acordeão, tais como exibir uma lista de <em>FAQs</em> (Perguntas frequentes, em português), exibir vários menus e submenus, exibir as localizações de uma empresa em particular, e assim adiante.</p><p>Neste artigo, verás como criar um menu acordeão em React completamente do zero, passo a passo, sem utilizar qualquer biblioteca externa.</p><p>Vamos utilizar a sintaxe de "React Hooks" para criar esta aplicação em React. Então, se não tiveres experiência em React Hooks, dá uma vista de olhos ao meu artigo <a href="https://levelup.gitconnected.com/an-introduction-to-react-hooks-50281fd961fe?source=friends_link&amp;sk=89baff89ec8bc637e7c13b7554904e54"><em>An introduction to React Hooks</em></a> (texto em inglês) para aprender os conceitos básicos dos Hooks.</p><p><strong>Podes ver uma demonstração da aplicação<strong> </strong><a href="https://react-accordion-demo.netlify.app/">aqui</a><strong>.</strong></strong></p><p>Então, vamos começar.</p><h2 id="configura-o-inicial-do-projeto"><strong>Configuração inicial do projeto</strong></h2><p>Cria um projeto utilizando <code>create-react-app</code>.</p><pre><code class="language-javascript">npx create-react-app react-accordion-demo
</code></pre><p>Assim que o projeto for criado, remove todos os ficheiros da pasta <code>src</code> e cria os ficheiros <code>index.js</code>, <code>App.js</code> e <code>styles.css</code> dentro da pasta <code>src</code>. Além disso, cria uma pasta com o novo <code>utils</code> dentro da pasta <code>src</code>.</p><p>Abre o ficheiro <code>styles.css</code> e adiciona os conteúdos <a href="https://github.com/myogeshchavan97/react-accordion-demo/blob/master/src/styles.css">daqui</a> dentro dele.</p><h2 id="como-criar-as-p-ginas-iniciais"><strong>Como criar as páginas iniciais</strong></h2><p>Abre o ficheiro <code>src/App.js</code> e adiciona o seguinte conteúdo dentro dele:</p><pre><code class="language-jsx">import React from 'react';

const App = () =&gt; {
  const accordionData = {
    title: 'Section 1',
    content: `Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quis sapiente
      laborum cupiditate possimus labore, hic temporibus velit dicta earum
      suscipit commodi eum enim atque at? Et perspiciatis dolore iure
      voluptatem.`
  };

  const { title, content } = accordionData;

  return (
    &lt;React.Fragment&gt;
      &lt;h1&gt;React Accordion Demo&lt;/h1&gt;
      &lt;div className="accordion"&gt;
        &lt;div className="accordion-item"&gt;
          &lt;div className="accordion-title"&gt;
            &lt;div&gt;{title}&lt;/div&gt;
            &lt;div&gt;+&lt;/div&gt;
          &lt;/div&gt;
          &lt;div className="accordion-content"&gt;{content}&lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/React.Fragment&gt;
  );
};

export default App;
</code></pre><p>Aqui, utilizamos as propriedades do objeto <code>accordionData</code> para exibir o conteúdo do acordeão.</p><p>Para a propriedade <code>content</code>, utilizamos a sintaxe de <em>template literals</em> do ES6 (``) de maneira a podermos distribuir o conteúdo por várias linhas e utilizamos algum texto <em>lorem ipsum</em> para preencher.</p><p>Agora, abre o ficheiro <code>src/index.js</code> e adiciona o seguinte conteúdo dentro dele:</p><pre><code class="language-jsx">import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './styles.css';

ReactDOM.render(&lt;App /&gt;, document.getElementById('root'));
</code></pre><p>Agora, se executares a aplicação utilizando o comando <code>yarn start</code> a partir do terminal, verás o seguinte ecrã:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/09/accordion_initial.png" class="kg-image" alt="accordion_initial" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/09/accordion_initial.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/09/accordion_initial.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/09/accordion_initial.png 1440w" sizes="(min-width: 1200px) 1200px" width="1440" height="655" loading="lazy"></figure><h2 id="como-abrir-e-fechar-o-menu-acorde-o"><strong>Como abrir e fechar o menu acordeão</strong></h2><p>Tal como podes ver acima, exibimos uma única secção como uma parte do acordeão. Por defeito, contudo, o acordeão está expandido e não podemos fechá-lo. Então, vamos adicionar a funcionalidade para abrir e fechar o acordeão.</p><p>Adiciona um novo estado dentro do componente, tal como mostrado abaixo:</p><pre><code class="language-js">const [isActive, setIsActive] = useState(false);
</code></pre><p>Aqui, definimos o estado <code>isActive</code>. Com base nisso, vamos ocultar ou exibir o conteúdo do acordeão.</p><p>Importa também o <em>hook</em> <code>useState</code> no início do ficheiro:</p><pre><code class="language-js">import React, { useState } from 'react';
</code></pre><p>Agora, para a <code>div</code> com a classe <code>accordion-title</code>, adiciona o manipulador <code>onClick</code>, desta forma:</p><pre><code class="language-jsx">&lt;div className="accordion"&gt;
  &lt;div className="accordion-item"&gt;
    &lt;div
      className="accordion-title"
      onClick={() =&gt; setIsActive(!isActive)}
    &gt;
      &lt;div&gt;{title}&lt;/div&gt;
      &lt;div&gt;{isActive ? '-' : '+'}&lt;/div&gt;
    &lt;/div&gt;
    {isActive &amp;&amp; &lt;div className="accordion-content"&gt;{content}&lt;/div&gt;}
  &lt;/div&gt;
&lt;/div&gt;
</code></pre><p>Aqui, estamos a inverter o valor do estado <code>isActive</code> quando clicamos na div <code>accordion-title</code>. Se o valor de <code>isActive</code> for <code>false</code>, estamos a defini-lo para &nbsp;<code>true</code>, e vice-versa.</p><p>Também estamos a exibir os sinais <code>+</code> ou <code>-</code> com base no valor de <code>isActive</code>, utilizando o operador ternário.</p><p>Se o valor de estado de <code>isActive</code> for <code>true</code>, vamos exibir apenas o conteúdo do acordeão, tal como mostrado abaixo:</p><pre><code class="language-jsx">{isActive &amp;&amp; &lt;div className="accordion-content"&gt;{content}&lt;/div&gt;}
</code></pre><p>Agora, se verificares a aplicação, verás o seguinte ecrã:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/09/open_close.gif" class="kg-image" alt="open_close" width="706" height="442" loading="lazy"></figure><p>Como podes observar, inicialmente, o acordeão está fechado. Quando clicamos no título, o acordeão abre e podemos clicar nele novamente para fechá-lo.</p><h2 id="como-adicionar-v-rias-sec-es-em-acorde-o"><strong>Como adicionar várias secções em acordeão</strong></h2><p>Isto funciona bem para uma única secção em acordeão. No entanto, se tivermos várias secções, não será bom copiar e colar o mesmo código JSX vezes sem conta com conteúdo diferente.</p><p>Então, vamos criar um componente separado para exibir apenas o acordeão. Depois, com base no número de secções, vamos iterar sobre o componente para exibir várias secções.</p><p>Cria um ficheiro <code>Accordion.js</code> dentro da pasta <code>src</code> e adiciona-lhe os seguintes conteúdos:</p><pre><code class="language-jsx">import React, { useState } from 'react';

const Accordion = ({ title, content }) =&gt; {
  const [isActive, setIsActive] = useState(false);

  return (
    &lt;div className="accordion-item"&gt;
      &lt;div className="accordion-title" onClick={() =&gt; setIsActive(!isActive)}&gt;
        &lt;div&gt;{title}&lt;/div&gt;
        &lt;div&gt;{isActive ? '-' : '+'}&lt;/div&gt;
      &lt;/div&gt;
      {isActive &amp;&amp; &lt;div className="accordion-content"&gt;{content}&lt;/div&gt;}
    &lt;/div&gt;
  );
};

export default Accordion;
</code></pre><p>Aqui, movemos o estado e a div <code>accordion-item</code> do ficheiro <code>App.js</code> para o ficheiro <code>Accordion.js</code>. Estamos a passar os <em>props</em> dinâmicos <code>title</code> e <code>content</code> para o componente utilizando a sintaxe de desestruturação do ES6, como isto:</p><pre><code class="language-js">const Accordion = ({ title, content }) =&gt; {
</code></pre><p>Agora, abre o ficheiro <code>App.js</code> e substitui-o pelo seguinte conteúdo:</p><pre><code class="language-jsx">import React from 'react';
import Accordion from './Accordion';

const App = () =&gt; {
  const accordionData = [
    {
      title: 'Section 1',
      content: `Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quis sapiente
      laborum cupiditate possimus labore, hic temporibus velit dicta earum
      suscipit commodi eum enim atque at? Et perspiciatis dolore iure
      voluptatem.`
    },
    {
      title: 'Section 2',
      content: `Lorem ipsum, dolor sit amet consectetur adipisicing elit. Mollitia veniam
      reprehenderit nam assumenda voluptatem ut. Ipsum eius dicta, officiis
      quaerat iure quos dolorum accusantium ducimus in illum vero commodi
      pariatur? Impedit autem esse nostrum quasi, fugiat a aut error cumque
      quidem maiores doloremque est numquam praesentium eos voluptatem amet!
      Repudiandae, mollitia id reprehenderit a ab odit!`
    },
    {
      title: 'Section 3',
      content: `Sapiente expedita hic obcaecati, laboriosam similique omnis architecto ducimus magnam accusantium corrupti
      quam sint dolore pariatur perspiciatis, necessitatibus rem vel dignissimos
      dolor ut sequi minus iste? Quas?`
    }
  ];

  return (
    &lt;div&gt;
      &lt;h1&gt;React Accordion Demo&lt;/h1&gt;
      &lt;div className="accordion"&gt;
        {accordionData.map(({ title, content }) =&gt; (
          &lt;Accordion title={title} content={content} /&gt;
        ))}
      &lt;/div&gt;
    &lt;/div&gt;
  );
};

export default App;
</code></pre><p>Aqui, convertemos <code>accordionData</code> de um objeto para um <em>array </em>de objetos. Estamos a iterar sobre ele utilizando o método de mapeamento de <em>array </em>e a passar os <code>title</code> e <code>content</code> correspondentes para o componente <code>Accordion</code>.</p><p>Agora, se verificares a aplicação, verás que as três secções são exibidas e que podemos abrir e fechar cada secção, tal como mostrado abaixo:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/09/final_working.gif" class="kg-image" alt="final_working" width="706" height="442" loading="lazy"></figure><h2 id="como-refatorar-o-c-digo"><strong>Como refatorar o código</strong></h2><p>Então, tal como podes ver, ao mover simplesmente a secção do acordeão para fora para uma componente separado e ao passar o conteúdo dinâmico como <em>props</em>, conseguimos criar com sucesso uma versão funcional de um acordeão a partir do zero.</p><p>É uma boa prática manter a informação estática num ficheiro à parte. Então, vamos mover o <em>array </em><code>accordionData</code> para um ficheiro diferente e importá-lo para <code>App.js</code>.</p><p>Cria um ficheiro chamado <code>content.js</code> dentro da pasta <code>utils</code> e adiciona-lhe o seguinte conteúdo:</p><pre><code class="language-js">export const accordionData = [
  {
    title: 'Section 1',
    content: `Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quis sapiente
    laborum cupiditate possimus labore, hic temporibus velit dicta earum
    suscipit commodi eum enim atque at? Et perspiciatis dolore iure
    voluptatem.`
  },
  {
    title: 'Section 2',
    content: `Lorem ipsum, dolor sit amet consectetur adipisicing elit. Mollitia veniam
    reprehenderit nam assumenda voluptatem ut. Ipsum eius dicta, officiis
    quaerat iure quos dolorum accusantium ducimus in illum vero commodi
    pariatur? Impedit autem esse nostrum quasi, fugiat a aut error cumque
    quidem maiores doloremque est numquam praesentium eos voluptatem amet!
    Repudiandae, mollitia id reprehenderit a ab odit!`
  },
  {
    title: 'Section 3',
    content: `Sapiente expedita hic obcaecati, laboriosam similique omnis architecto ducimus magnam accusantium corrupti
    quam sint dolore pariatur perspiciatis, necessitatibus rem vel dignissimos
    dolor ut sequi minus iste? Quas?`
  }
];
</code></pre><p>Agora, abre <code>App.js</code> e substitui-o pelo seguinte conteúdo:</p><pre><code class="language-jsx">import React from 'react';
import Accordion from './Accordion';
import { accordionData } from './utils/content';

const App = () =&gt; {
  return (
    &lt;div&gt;
      &lt;h1&gt;React Accordion Demo&lt;/h1&gt;
      &lt;div className="accordion"&gt;
        {accordionData.map(({ title, content }) =&gt; (
          &lt;Accordion title={title} content={content} /&gt;
        ))}
      &lt;/div&gt;
    &lt;/div&gt;
  );
};

export default App;
</code></pre><p>Aqui, apenas importamos a informação estática do ficheiro externo e removêmo-la do ficheiro <code>App.js</code>.</p><p>Então, agora o código está mais limpo e fácil de compreender e a funcionalidade está a funcionar como antes.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/09/final_working--1-.gif" class="kg-image" alt="final_working--1-" width="706" height="442" loading="lazy"></figure><h2 id="pontos-finais"><strong>Pontos finais</strong></h2><p>Terminamos a construção da funcionalidade da nossa aplicação.</p><p><strong>Podes encontrar o código fonte completo desta aplicação no <strong>GitHub </strong></strong><a href="https://github.com/myogeshchavan97/react-accordion-demo"><strong>neste repositório</strong></a><strong><strong>.</strong></strong></p><h3 id="obrigado-pela-leitura-"><strong>Obrigado pela leitura!</strong></h3><p>Desejas aprender todas as funcionalidades do ES6+ em detalhe, incluindo <em>let</em> e <em>const</em>, <em>promises</em>, vários métodos de <em>promises</em>, <em>arrays</em> e desestruturação de objetos, funções de seta, <em>async</em>/<em>await</em>, importação e exportação e muito mais a partir do zero?</p><p>Consulta o meu livro "<a href="https://modernjavascript.yogeshchavan.dev/">Mastering Modern JavaScript</a>" (em inglês). Ele aborda todos os pré-requisitos para aprender React e ajuda-te a ficar mais competente em JavaScript e React.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/09/freecodecamp_image-1.jpeg" class="kg-image" alt="freecodecamp_image-1" width="512" height="800" loading="lazy"></figure> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como implantar uma aplicação do React em produção na AWS usando Express, Postgres, PM2 e nginx ]]>
                </title>
                <description>
                    <![CDATA[ Neste tutorial, vou guiá-lo através de uma configuração de implantação em nível de produção na AWS a partir do zero. Vou presumir que você tem pouco ou nenhum conhecimento prévio sobre AWS e que você é um iniciante. Configuraremos uma aplicação full-stack do React Express com um banco de dados ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-implantar-uma-aplicacao-do-react-em-producao-na-aws-usando-express-postgres-pm2-e-nginx/</link>
                <guid isPermaLink="false">66d1c06b7d7d51e388cf626a</guid>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Daniel Rosa ]]>
                </dc:creator>
                <pubDate>Fri, 30 Aug 2024 13:51:40 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2024/08/5f9ca067740569d1a4ca4878.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/production-fullstack-react-express/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to deploy a React app to production on AWS using Express, Postgres,  PM2 and nginx</a>
      </p><p>Neste tutorial, vou guiá-lo através de uma configuração de implantação em nível de produção na AWS a partir do zero. Vou presumir que você tem pouco ou nenhum conhecimento prévio sobre AWS e que você é um iniciante.</p><p>Configuraremos uma aplicação <em>full-stack</em> do React Express com um banco de dados PSQL. Implantaremos a aplicação em uma instância da AWS EC2 executando uma Amazon Linux AMI 2. A configuração usará NGINX como um proxy reverso e PM2 como o gerenciador de clusters. O banco de dados PSQL será implantado na AWS RDS.</p><p>Vamos nos manter dentro do nível gratuito. Assim, seguir este tutorial não custará nada.</p><p><strong>Por que aprender AWS?</strong><br>AWS é atualmente a maior plataforma de computação em nuvem. O Wordpress alimenta mais sites pequenos, mas a AWS é usada pela grande maioria dos sites comerciais de alto tráfego. Isso significa que pessoas com habilidades em AWS estão em grande demanda.</p><p>Você pode assistir a uma versão em vídeo deste tutorial <a href="https://www.youtube.com/watch?v=RoPlkFRHqgE&amp;list=PLMc67XEAt-yzxRboCFHza4SBOxNr7hDD5&amp;pp=iAQB">aqui</a>.</p><p><strong>Comandos úteis do terminal:</strong><br><a href="https://github.com/iqbal125/terminal_commands_fullstack">https://github.com/iqbal125/terminal_commands_fullstack</a></p><h2 id="teoria">Teoria</h2><ul><li><strong>Como funciona a rede na computação em nuvem da AWS</strong></li><li><strong>Instância da AWS EC2</strong></li><li><strong>Endereços IP públicos x privados</strong></li><li><strong>Endereços IPv4</strong></li><li><strong>Conectando-se à internet pública a partir de uma rede privada</strong></li><li><strong>Visão geral conceitual da VPC da AWS</strong></li><li><strong>Como funcionam as sub-redes na AWS</strong></li><li><strong>SSH</strong></li></ul><h2 id="pr-tica">Prática</h2><ul><li><strong>Implantação simples do EBS</strong></li><li><strong>Configuração da VPC e sub-redes</strong></li><li><strong>Gateways da internet e tabelas de roteamento</strong></li><li><strong>Configuração de grupos de segurança</strong></li><li><strong>Implantação de um computador em nuvem com AWS EC2</strong></li><li><strong>Configuração do banco de dados na AWS</strong></li><li><strong>Configuração da build do React para produção</strong></li><li><strong>Configuração do PM2</strong></li><li><strong>Configuração do Nginx</strong></li></ul><h2 id="teoria-1">Teoria</h2><p>A computação em nuvem simplificou drasticamente a implantação de uma aplicação para a web. Sites como Digital Ocean e Heroku tornam o processo ainda mais fácil ao ocultar toda a complexidade e permitir que você implante sua aplicação com alguns passos simples.</p><p>Essas ferramentas são boas, mas o que queremos é uma configuração de computação em nuvem robusta, altamente segura e altamente performática, o que significa que vamos fazer isso do zero.</p><p>A configuração da AWS envolverá principalmente a rede. É por isso que a maior parte deste tutorial focará em conceitos e configurações de rede.</p><p>Todo o resto, como o provisionamento dos bancos de dados e instâncias EC2, é fácil de fazer na AWS. A rede será o maior desafio.</p><p>Não se preocupe, no entanto, se você não tiver nenhuma experiência em rede. Vou fornecer todas as informações de que você precisa saber.</p><h3 id="como-funciona-a-rede-na-computa-o-em-nuvem">Como funciona a rede na computação em nuvem</h3><p>Ela funciona basicamente da mesma maneira que a rede funciona com hardware, exceto pelo fato de que todo o hardware (roteadores, switches, gateways de internet) é virtualizado na computação em nuvem.</p><p>A rede na computação em nuvem determina essencialmente como seus recursos virtuais se comunicam entre si e com a internet em geral.</p><p>VPCs, endereços IP e sub-redes são os conceitos mais importantes para entender sobre redes na AWS.</p><p>Isso é basicamente o que criaremos.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-1.png" class="kg-image" alt="image-1" width="600" height="400" loading="lazy"></figure><p>Teremos uma sub-rede pública e uma sub-rede privada em nossa VPC. A sub-rede pública conterá nosso servidor da web e será acessível pela internet. Nossa sub-rede privada conterá nosso banco de dados, mas não será acessível pela internet.</p><p>Nosso servidor da web e nosso banco de dados poderão se comunicar entre eles através de uma tabela de rotas.</p><p>Veremos exemplos dos dois quando configurarmos nosso projeto no console da AWS.</p><h3 id="endere-os-ip-p-blicos-x-privados">Endereços IP públicos x privados</h3><p>Um endereço IP público é a localização de onde seu computador está na internet. No entanto, o que chamamos de internet é apenas uma das muitas redes.</p><p>Da mesma maneira que você pode ter um endereço IP na internet, você também pode ter um endereço IP em outra rede que não seja a internet.</p><p>O endereço IP é simplesmente um modo de identificar um único computador em uma rede, independentemente de essa rede ser a internet ou não.</p><p>Portanto, endereços IP privados são apenas uma maneira de identificar computadores em nossa própria rede e endereços IP públicos são uma maneira de identificar computadores na rede chamada "internet".</p><h3 id="ipv4">IPv4</h3><p>IPv4 é o formato em que os endereços IP são escritos.</p><p>Exemplo de endereço IPv4: 10.12.15.22</p><p>Chamado de IPv4, pois existem 4 bytes que podem representar o endereço. Cada byte contém 8 bits e, portanto, é referido como um <strong>octeto</strong>.</p><p>Como cada octeto contém 8 bits e cada bit pode ser 0 ou 1, há 2 ^ 8 = 256 combinações diferentes. Começamos em 0. Então, um octeto pode ser um número entre 0-255. Como temos 4 octetos, temos 256 ^ 4 = 4,3 bilhões de combinações diferentes e, portanto, endereços IP!</p><p>Um endereço IPv4 é resolvido para um formato legível por humanos: "<a href="https://google.com">https://google.com</a>" através de um DNS.</p><p>Também existe o IPv6, mas, para manter as coisas concisas, vamos pular isso. Precisaremos apenas conhecer o IPv4 para os fins deste tutorial.</p><h3 id="conectando-se-rede-p-blica-a-partir-de-uma-rede-privada">Conectando-se à rede pública a partir de uma rede privada</h3><p>Isso é feito através de um gateway da internet.</p><p>Quando uma solicitação é feita por um computador em uma rede privada, uma tabela de roteamento verifica se o destino é para um computador local ou não.</p><p>Se não for, a solicitação é encaminhada para o gateway da internet, que a encaminha para fora da rede privada e para um Provedor de Serviço de Internet, que, então, a envia para o destino pretendido.</p><p>O gateway da internet também recebe solicitações da internet.</p><p>O gateway da internet tem seu próprio endereço IP público. Uma rede pode ter somente um endereço IP público, mesmo que tenha milhares de endereços IP privados.</p><p>O protocolo usado para enviar e receber dados é chamado de TCP. Este é um padrão e um modelo que assegura a integridade e confiabilidade dos dados.</p><h3 id="vpc-e-sub-redes">VPC e sub-redes</h3><p>VPC e sub-redes são, de longe, as coisas mais difíceis de entender e aprender na AWS. Por isso, dedicarei uma seção mais longa a eles.</p><p>A <strong>Nuvem Privada Virtual</strong> (em inglês, VPC ou virtual private cloud) é uma localização virtual onde você pode implantar recursos da AWS. Você pode implantar servidores da web, bancos de dados, servidores de arquivos e serviços de mensagens em uma VPC e ter todos os seus recursos contidos em um único lugar virtual.</p><p>Cada recurso tem seu próprio endereço IP privado.</p><p>Uma <strong>sub-rede (subnet)</strong> é uma parte menor da sua VPC inteira. As sub-redes são, essencialmente, uma maneira de dividir sua VPC por razões de desempenho e segurança.</p><p><strong>Exemplo:</strong> utilizamos isso para implantar um banco de dados em uma sub-rede que seja inacessível pela internet, enquanto uma outra sub-rede possui os servidores da web que precisarão ser acessíveis pela internet. Mesmo que essas duas sub-redes sejam separadas, elas ainda fazem parte da mesma VPC.</p><p>As sub-redes na AWS são feitas com a notação CIDR.</p><p><strong><strong>Exemplo de notação CIDR para sub-rede:</strong></strong> 10.11.12.0/24</p><p><strong>Máscara de sub-rede</strong><br>A máscara de sub-rede determina o número de endereços IP disponíveis para a sub-rede. O /24 é a máscara de sub-rede.</p><p>Uma máscara de sub-rede é usada como uma maneira de dividir sua sub-rede em um número aproximado de endereços IP.</p><p><strong>Prefixo de rede</strong>: são os octetos iniciais inalteráveis que identificam uma sub-rede ou VPC única.</p><p><strong>Endereço do host</strong>: os endereços IP disponíveis para uso nos diferentes recursos em uma sub-rede.</p><p>/24 significa que os primeiros 24 bits devem ser usados como prefixo de rede e, portanto, são inutilizáveis. Como um IPv4 tem 32 bits no total, temos 8 bits restantes, que são conhecidos como endereço do host. Esses são os endereços IP utilizáveis. Como 8 bits têm 256 combinações, nossa sub-rede pode ter qualquer endereço entre 10.11.12.0 e 10.11.12.255</p><p>Os números 1 representam o prefixo de rede e os números 0 representam o endereço do host</p><p>/24 = 255.255.255.0 = 11111111.11111111.11111111.00000000</p><p><strong>Isso é igual a:</strong></p><p>10.11.12.0/24</p><p>10.11.12.0/255.255.255.0</p><p>10.11.12.0/11111111.11111111.11111111.00000000</p><p>Uma sub-rede não precisa ser dividida uniformemente em octetos.</p><p>10.11.12.0 /19 significa uma máscara de sub-rede de 11111111.11111111.11100000.0000000</p><p>Se formos a um calculador de sub-rede, podemos ver como isso funciona. Um calculador de sub-rede fornece o número de endereços IP disponíveis em uma sub-rede, além de fornecer o endereço IP mínimo e máximo.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-71.png" class="kg-image" alt="image-71" width="600" height="400" loading="lazy"></figure><p>Como você pode ver, essa sub-rede nos dá um total de 8190 endereços IP utilizáveis.</p><p>Os dois primeiros octetos são todos 1s. Então, eles são usados como o prefixo de rede e podem ser qualquer número entre 0-255.</p><p>Nosso terceiro octeto, porém, tem apenas o prefixo de rede parcial e temos apenas 5 bits para usar como nosso endereço do host. Isso significa que o segundo octeto pode ser apenas um número entre 0-31, já que 2 ^ 5 = 32.</p><p>Nosso último octeto é todo 0, então, normalmente, pode ser qualquer número entre 0-255.</p><p>Tudo isso significa que nossa sub-rede pode ter qualquer endereço entre</p><p>10.11.0.0 - 10.11.31.255</p><p><strong>Observação:</strong> os primeiros e últimos endereços IP são usados como endereços de rede e transmissão, que são endereços IP especiais com funções especiais. É por isso que o Host min é o segundo endereço IP e o Host Max é o penúltimo endereço IP.</p><p>Você pode aprender mais sobre endereços de rede e transmissão <a href="https://www.computernetworkingnotes.com/ccna-study-guide/network-address-basic-concepts-explained-with-examples.html">aqui</a> (em inglês):</p><p>Para evitar toda a complexidade mencionada acima, é melhor ficar com máscaras de sub-rede de /8 /16 /24. Fazendo isso, você garantirá que não haverá octetos parciais.</p><p>10.11.12.0/8 terá os últimos 3 octetos inteiros disponíveis como endereços IP</p><p>10.11.12.0/16 terá os últimos 2 octetos inteiros disponíveis como endereços IP</p><p>10.11.12.0/24 terá o último 1 octeto inteiro disponível como endereços IP</p><p>Exemplo real<br><strong>VPC:</strong> 10.11.0.0/16</p><p><strong>Sub-rede pública 1:</strong> 10.11.1.0/24, qualquer endereço IP entre 10.11.1.0 e 10.11.1.255<br><strong>Sub-rede pública 2:</strong> 10.11.2.0/24, qualquer endereço IP entre 10.11.2.0 e 10.11.2.255</p><p><strong>Sub-rede privada 1:</strong> 10.11.3.0/24, qualquer endereço IP entre 10.11.3.0 e 10.11.3.255 </p><p><strong>Sub-rede privada 2:</strong> 10.11.4.0/24, qualquer endereço IP entre 10.11.4.0 e 10.11.4.255</p><p><strong>Observação:</strong> nem todos os endereços IP estarão disponíveis para sua sub-rede. Alguns endereços, como os de rede e de transmissão, bem como alguns outros endereços de utilidade, serão reservados pela AWS.</p><h3 id="aws-ec2">AWS EC2</h3><p>É o "computador" na computação em nuvem. É essencialmente um computador virtual. Tem tudo o que seu computador doméstico possui: CPU, RAM, disco rígido etc.</p><p>Existem também outros sistemas operacionais Linux disponíveis, como Ubuntu e Red Hat, assim como sistemas operacionais baseados em Windows disponíveis, tais como o Windows Server. Sistemas Windows permitem que você use uma interface gráfica de usuário (GUI) se preferir não trabalhar com a linha de comando.</p><p>Um único computador EC2 é referido como uma instância.</p><h3 id="ssh">SSH</h3><p><strong>Secure shell:</strong> usado para fazer login no nosso servidor Linux EC2 a partir do nosso computador pessoal.</p><p>Você pode usar o Putty para SSH se preferir uma interface gráfica.</p><p>Eu usarei o Git Bash. É mais simples de usar, mas não tem uma GUI.</p><p>Vamos utilizar chaves privadas e públicas para SSH. Ambas são geradas pela AWS.</p><p>A chave privada será armazenada no seu próprio computador e será usada durante o processo de login.</p><p>A chave pública será armazenada na Amazon e permitirá os logins. A chave pública não precisa ser mantida em segredo. A chave privada deve ser mantida em um lugar seguro no seu computador. Se você a apagar acidentalmente, não há como obter outra.</p><h2 id="pr-tica-1">Prática</h2><p><strong>Implantação simples do EBS</strong></p><p>Antes de fazer nossa implantação complexa, podemos fazer uma implantação simples do EBS para nos familiarizarmos.</p><p>AWS Elastic Beanstalk é uma maneira de lançar uma aplicação na nuvem sem precisar configurar manualmente os recursos subjacentes, como o VPC, servidor da web e banco de dados. É muito fácil e rápido ter uma aplicação em execução no AWS ELB e é uma boa maneira de se familiarizar com a AWS.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-5.png" class="kg-image" alt="image-5" width="600" height="400" loading="lazy"></figure><p>Vá para a página inicial da AWS e crie uma nova conta se você ainda não tiver uma.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-6.png" class="kg-image" alt="image-6" width="600" height="400" loading="lazy"></figure><p>Depois, acesse Services e, em seguida, ElasticBeanStalk, em "Compute".</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-7.png" class="kg-image" alt="image-7" width="600" height="400" loading="lazy"></figure><p>Isso o levará à página inicial do EBS. Após isso, avance e clique em <em>Create New Application</em> e depois dê um nome e descrição para sua aplicação.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-8.png" class="kg-image" alt="image-8" width="600" height="400" loading="lazy"></figure><p>Você pode, então, clicar em <em>Create New Environment</em> e depois selecionar <em>Web server environment</em>.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-9.png" class="kg-image" alt="image-9" width="600" height="400" loading="lazy"></figure><p>Nesta página, selecione Node.js como a plataforma e use o código da aplicação de exemplo. Todo o resto pode ser deixado como padrão.</p><p>Eu não tive sorte ao implantar a aplicação diretamente daqui. Então, vamos clicar em <em>Configure more options</em> para configurar o projeto um pouco mais.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-10.png" class="kg-image" alt="image-10" width="600" height="400" loading="lazy"></figure><p>Clique no card de rede na parte inferior da página e certifique-se de que o VCP padrão está sendo usado junto com a sub-rede padrão marcada.</p><p>Depois, clique no card Instances e certifique-se de que a caixa de grupos de segurança padrão esteja marcada.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-11.png" class="kg-image" alt="image-11" width="600" height="400" loading="lazy"></figure><p>É isso. Agora, podemos clicar em <em>Create environment</em> para lançar nossa aplicação.</p><p>Se funcionou, você deve ver o ambiente lançado com sucesso na sua tela.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-12.png" class="kg-image" alt="image-12" width="600" height="400" loading="lazy"></figure><p>Se você clicar no URL, poderá ver sua aplicação implantada.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-13.png" class="kg-image" alt="image-13" width="600" height="400" loading="lazy"></figure><p>Parabéns por implantar uma aplicação na nuvem da AWS!</p><p><strong>Importante: certifique-se de excluir depois para não ser cobrado por usar a AWS.</strong></p><p>Para excluir, simplesmente clique em <em>Terminate Environment</em> em Actions. Isso excluirá a aplicação junto com todos os recursos subjacentes.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-14.png" class="kg-image" alt="image-14" width="600" height="400" loading="lazy"></figure><p>Agora, podemos passar para a configuração complexa.</p><h3 id="configura-o-do-vpc">Configuração do VPC</h3><p>Primeiro, podemos ir para o painel de controle do VPC, que está na seção <em>Network &amp; Content Delivery</em>.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-15.png" class="kg-image" alt="image-15" width="600" height="400" loading="lazy"></figure><p>Você deve estar na tela de dashboard do VPC. Lá, você pode criar um VPC com o botão Launch VPC Wizard (que é um pouco mais fácil), mas eu mostrarei como configurá-lo do zero (que é um pouco mais difícil), mas dará a você uma melhor compreensão de como um VPC funciona.</p><p>Primeiro, clique na aba VPCs e clique no botão <em>Create VPC</em>, que levará você a uma página semelhante a esta.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-16.png" class="kg-image" alt="image-16" width="600" height="400" loading="lazy"></figure><p>Podemos nomear o VPC como VPC 3.</p><p>Podemos definir o bloco CIDR para 10.11.0.0/16. Se você se lembra das seções de Teoria de VPC e sub-rede, isso significa que os dois primeiros octetos são o prefixo da rede e os últimos dois octetos são o endereço do host. Eles estão disponíveis para nossa utilização.</p><p><em>Tenancy</em> significa que o VPC estará em seu próprio hardware dedicado ou não. Há uma percepção de que a <em>Tenancy </em>dedicada é mais segura ou tem melhor desempenho, mas não há dados para sugerir isso.</p><p>A <em>Tenancy</em> padrão (em inglês, <em>default</em>) significa que seu VPC compartilhará o hardware subjacente com outros usuários da AWS, mas será isolado deles através de software.</p><p>Depois disso, podemos clicar em <em>Create VPC</em>, finalizando nossa configuração do VPC.</p><h3 id="configura-o-de-sub-redes">Configuração de sub-redes</h3><p>A seguir, configuraremos as sub-redes. Podemos começar clicando na aba <em>Subnets </em>e clicar em <em>Create subnet</em>.</p><p>Vamos primeiro criar nossa sub-rede pública, assim:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-17.png" class="kg-image" alt="image-17" width="600" height="400" loading="lazy"></figure><p>10.11 é nosso prefixo de rede inalterável da nossa VPC, o que faz com que .1 também faça parte do prefixo da rede, já que a máscara de sub-rede é /24 e .1 é também o identificador dessa sub-rede.</p><p>O último octeto, então, serve como endereço do host, o que significa que esta sub-rede pode ter qualquer endereço entre 10.11.1.0 - 10.11.1.255.</p><p>Depois disso, podemos clicar em <em>Create</em>, o que criará a sub-rede e a listará sob as sub-redes.</p><p>Passemos para nossa sub-rede privada:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-18.png" class="kg-image" alt="image-18" width="600" height="400" loading="lazy"></figure><p>Ela é configurada de maneira similar à sub-rede pública, com a principal diferença sendo que a terceira casa decimal é .2 ao invés de .1. Também precisamos especificar uma zona de disponibilidade para fazer essa sub-rede funcionar com nosso banco de dados.</p><p>Então, basicamente, 10.11 é o prefixo de rede que obtivemos da VPC. .2 é a terceira casa decimal e o identificador único para esta sub-rede. O último octeto, .0, são os endereços IP disponíveis entre 0-255.</p><p>Isso significa que esta sub-rede pode ter qualquer endereço IP de 10.11.2.0 - 10.11.2.255.</p><p>Se você comparar isso com nossa sub-rede pública, que tem um intervalo de endereços IP de 10.11.1.0 -10.11.1.255, ficará muito mais claro qual é o padrão para configurar a sub-rede.</p><p>Implantar um banco de dados na AWS requer 2 sub-redes em diferentes zonas de disponibilidade, então você pode configurar a segunda assim:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-19.png" class="kg-image" alt="image-19" width="600" height="400" loading="lazy"></figure><h3 id="gateways-de-internet-e-tabelas-de-roteamento">Gateways de internet e tabelas de roteamento</h3><p><strong>Tabelas de roteamento</strong> são essencialmente roteadores e determinam como e para onde o tráfego é direcionado.</p><p>Agora, podemos criar um gateway de internet que anexaremos à nossa sub-rede pública.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-20.png" class="kg-image" alt="image-20" width="600" height="400" loading="lazy"></figure><p>Como todos os gateways de internet funcionam da mesma maneira, só precisamos definir o nome. Antes de podermos anexar este gateway de internet à nossa sub-rede, precisamos primeiro configurar a tabela de roteamento.</p><p>Podemos ir para a aba <em>Route Tables</em> e clicar em <em>Create route table</em>.</p><p>Só temos que definir o nome e associá-la à VPC. Podemos associá-la à VPC 3 e então clicar em criar.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-21.png" class="kg-image" alt="image-21" width="600" height="400" loading="lazy"></figure><p>Uma vez feito isso, podemos anexar nosso gateway de internet a essa VPC. Vamos voltar para a aba do gateway de internet, clicar no botão Actions e, depois, em Attach to VPC.</p><p>Para a opção de anexar, basta selecionar a VPC 3.</p><p>Em seguida, podemos voltar à nossa tabela de roteamento que configuramos e adicionar uma rota. Podemos adicionar a rota assim.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-22.png" class="kg-image" alt="image-22" width="600" height="400" loading="lazy"></figure><p>Isso está dizendo que, se for feita uma solicitação, a tabela de roteamento primeiro verifica se a rota é para uma rota local 10.11.0.0/16. Caso contrário, encaminhamos essa solicitação para o gateway de internet para todas as outras rotas que são representadas por 0.0.0.0/0.</p><p>Então, podemos clicar na aba de associações de sub-rede e depois no botão <em>Edit subnet associations</em>.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-23.png" class="kg-image" alt="image-23" width="600" height="400" loading="lazy"></figure><p>Queremos apenas que a sub-rede pública esteja associada a essa tabela de roteamento. Então, marcamos apenas essa e podemos clicar em Save.</p><p>Não podemos nos esquecer das nossas sub-redes privadas. Basta criar outra tabela de roteamento e associar as sub-redes privadas a ela da mesma maneira que fizemos para a sub-rede pública. Não adicione um gateway de internet, apenas deixe a tabela de roteamento para alvos locais.</p><h3 id="grupos-de-seguran-a">Grupos de segurança</h3><p><strong>Grupos de segurança</strong> são essencialmente <em>firewalls </em>que filtram o tráfego de entrada e saída.</p><p>Precisamos configurar os grupos de segurança para trabalhar com essa configuração. Clique na aba de <em>Security Groups</em> e clique em <em>Create security group</em>.</p><p>Criar o grupo de segurança é muito fácil. Podemos apenas definir o nome e a descrição e associá-lo à nossa VPC 3.</p><p>Depois de criar os grupos de segurança, clique em <em>Edit inbound rules</em>.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-24.png" class="kg-image" alt="image-24" width="600" height="400" loading="lazy"></figure><p>Em seguida, podemos configurar as regras de segurança assim:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-25.png" class="kg-image" alt="image-25" width="600" height="400" loading="lazy"></figure><p>Primeiro, temos o SSH que usamos para fazer login na nossa instância do Ec2 a partir do nosso computador pessoal. Deixei a origem como 0.0.0.0/0, porque não quero colocar meu endereço IP pessoal, mas, em uma aplicação real, você vai querer colocar seu próprio endereço IP aqui.</p><p>Depois disso, temos a porta normal 80 e a porta 443, que permitem o tráfego normal pela internet. ::/0 permite todo o tráfego IPv6 junto com IPv4.</p><h3 id="lan-ando-uma-inst-ncia-do-ec2-computador-em-nuvem-">Lançando uma instância do EC2 (computador em nuvem)</h3><p>Primeiro, vamos ao painel do EC2 e clicamos em <em>Launch instance</em>. Em seguida, podemos selecionar o Amazon Linux AMI como o sistema operacional.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-26.png" class="kg-image" alt="image-26" width="600" height="400" loading="lazy"></figure><p>Então, para permanecer na camada gratuita, selecione a opção t.2 micro para o tipo de instância.</p><p>No terceiro passo, temos que configurar os detalhes da instância, o que podemos fazer assim:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-27.png" class="kg-image" alt="image-27" width="600" height="400" loading="lazy"></figure><p>Para a rede, podemos selecionar nossa VPC 3 e, para nossa sub-rede, podemos selecionar nossa sub-rede pública. Como este é nosso servidor da web, queremos que ele esteja em nossa sub-rede pública anexada a um gateway de internet.</p><p>Adicionar tags e adicionar armazenamento podem ser deixados como padrão.</p><p>Para a segurança, certifique-se de adicionar o grupo de segurança do servidor da web que configuramos na última seção.</p><p>Isso vai gerar um <em>pop-up</em> para oferecer um par de chaves. Podemos seguir em frente e selecionar criar um par de chaves. Em seguida, podemos baixar esse par de chaves.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-28.png" class="kg-image" alt="image-28" width="600" height="400" loading="lazy"></figure><p>Se feito corretamente, você deverá ver isto na sua tela:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-29.png" class="kg-image" alt="image-29" width="600" height="400" loading="lazy"></figure><p>Depois disso, nossa instância é lançada e está disponível para acessarmos via SSH. Podemos acessar nossa instância com o comando:</p><p><code>ssh -i “keypair.pem” ec2-user@public-ip-address</code></p><h3 id="configura-o-do-banco-de-dados">Configuração do banco de dados</h3><p>Vamos agora configurar o banco de dados. Podemos começar indo até a aba RDS na seção <em>Databases</em>, em <em>Services</em>. Isso nos levará ao <em>dashboard</em> <em>RDS Database</em>.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-30.png" class="kg-image" alt="image-30" width="600" height="400" loading="lazy"></figure><p>Antes de podermos criar um banco de dados, temos que criar primeiro um grupo de sub-rede. Para começar, podemos ir até a aba de grupos de sub-rede e clicar em <em>Create db subnet group</em>.</p><p>Um grupo de sub-rede de bancos de dados serve para proteger contra qualquer tipo de falha total do servidor ou exclusão acidental. É por isso que ele abrange 2 zonas de disponibilidade. No caso remoto de um servidor falhar completamente em uma zona de disponibilidade, seu banco de dados ainda estará bem. É extremamente improvável que os dois servidores falhem completamente em 2 zonas de disponibilidade diferentes ao mesmo tempo.</p><p>Primeiro, definimos o nome e a descrição. Depois, associamos nossa VPC 3 ao grupo de sub-rede. Após isso, podemos adicionar nossas sub-redes.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-31.png" class="kg-image" alt="image-31" width="600" height="400" loading="lazy"></figure><p>As sub-redes serão listadas sob a zona de disponibilidade onde as configuramos, na seção anterior. Depois, podemos apenas clicar em <em>Create</em>.</p><p>Depois de criar o grupo de sub-rede, estamos prontos para criar nosso banco de dados real.</p><p>Podemos primeiro selecionar a opção elegível para o nível gratuito no final.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-32.png" class="kg-image" alt="image-32" width="600" height="400" loading="lazy"></figure><p>Em seguida, clicamos em <em>Next</em>. Podemos deixar todas as outras configurações na próxima página com as opções padrão. Certifique-se de lembrar do nome de usuário e senha definidos aqui.</p><p>Na próxima página, podemos definir a VPC como nossa VPC 3, o grupo de sub-rede para o que acabamos de configurar.</p><p>Certifique-se também de deixar "Public acessibility" marcado como não. Por razões óbvias de segurança, não queremos que nossa aplicação esteja disponível na internet.</p><p>Todo o resto pode ser deixado como padrão. Configuraremos nossos grupos de segurança do banco de dados em um segundo.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-33.png" class="kg-image" alt="image-33" width="600" height="400" loading="lazy"></figure><p>Agora, podemos clicar em <em>Create database</em> e criar os grupos de segurança do banco de dados enquanto o banco de dados está sendo criado.</p><p>Podemos ir até a aba de grupos de segurança no <em>dashboard</em> da VPC e criar um grupo de segurança, como vimos anteriormente. Para as regras de entrada, podemos limitá-las ao intervalo CIDR do nosso servidor da web, com a porta configurada para a porta padrão 5432 do PSQL.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-34.png" class="kg-image" alt="image-34" width="600" height="400" loading="lazy"></figure><p>Clique em <em>Create</em> e estamos prontos para adicionar isso ao nosso banco de dados.</p><p>Para adicionar este novo grupo de segurança, podemos ir até o banco de dados no painel de controle do banco de dados. Depois, clique no botão <em>Modify</em>.</p><p>Depois disso, podemos apenas selecionar o grupo de segurança que acabamos de configurar na seção de rede e segurança.</p><p>Uma pergunta que você pode ter agora é como se conectar ao nosso banco de dados se ele não é publicamente acessível na internet.</p><p>A maneira de se fazer isso é, primeiro, acessando via SSH nossa instância do Linux e depois se conectanado ao nosso banco de dados a partir dessa instância sobre a porta TCP do PSQL, que configuramos na nossa tabela de rotas.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-35.png" class="kg-image" alt="image-35" width="600" height="400" loading="lazy"></figure><p>Para testar isso, podemos acessar via SSH nossa instância do EC2 da mesma maneira vista acima. Em seguida, podemos instalar o psql com o comando:</p><p><code>sudo amazon-linux-extras install postgresql9.6</code></p><p>Depois, podemos nos conectar ao banco de dados psql com o seguinte comando:</p><p><code>psql -d nome-do-bd -h nome-do-host -p porta -U nome-de-usuário</code></p><p>Se conectado com sucesso, você verá o nome do seu banco de dados seguido de uma seta.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-36.png" class="kg-image" alt="image-36" width="600" height="400" loading="lazy"></figure><h3 id="configura-o-do-projeto-do-react-e-do-node">Configuração do projeto do React e do Node</h3><p>Aqui, vou abordar uma configuração de exemplo com React e node/express. A primeira coisa a fazer é executar o comando <code>npm run build</code>, que gerará uma <em>build </em>de produção de sua aplicação em um diretório chamado <strong>build.</strong></p><p><strong>Observação</strong>: certifique-se de que todas as rotas do localhost na sua versão de <em>build </em>sejam alteradas para o IP público. Isso é provavelmente verdade para autenticação. Todo o resto pode ser deixado como está.</p><p>Corte e cole todo este diretório <em>build</em> em um servidor node/express. Depois, defina um caminho para ele, conforme mostrado abaixo.</p><pre><code class="language-javascript">....
//servidor express

app.use(express.static(path.join(__dirname, 'build')));

if(process.env.NODE_ENV === 'production') {
  app.get('/*', function (req, res) {
   	res.sendFile(path.join(__dirname, 'build', 'index.html'));
  });
}

....
</code></pre><p>A primeira função é como servimos os arquivos estáticos da nossa aplicação do React (os arquivos JS, CSS, PWA).</p><p>A segunda função verifica se o ambiente é de produção e, então, serve o principal arquivo HTML do React.</p><p>Essa abordagem mantém nosso roteamento do lado do <em>client</em> intacto. Por exemplo, na nossa <em>build </em>de desenvolvimento podemos usar rotas como /post/22 e isso será roteado corretamente para <a href="http://localhost:3000/post/22">http://localhost:3000/post/22</a>.</p><p>Depois disso, basta fazer a implantação do projeto do React Express em um repositório do Github.</p><p>É isso. Depois, podemos implantar essa aplicação do React Express em um servidor Linux.</p><h3 id="implantando-o-projeto-na-inst-ncia-aws-ec2">Implantando o projeto na instância AWS EC2</h3><p>Agora, estamos prontos para implantar nosso projeto. Primeiro, use o SSH na sua instância EC2 com o Gitbash por meio do seguinte comando:</p><p><code>ssh -i "keypair.pem" ec2-user@endereco-ip-publico</code></p><p>A próxima coisa que precisamos fazer é instalar o git, com o comando:</p><p><code>sudo yum install git</code></p><p>Então, podemos clonar o projeto no servidor com o comando</p><p><code>sudo git clone link-to-repo</code></p><p>Depois de fazer isso, você deve conseguir ver os arquivos do seu projeto fazendo <code>cd</code> no diretório.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-62.png" class="kg-image" alt="image-62" width="600" height="400" loading="lazy"></figure><p>Ainda não terminamos. Precisamos instalar o node e o npm, porque queremos instalar as dependências do nosso projeto. Primeiro, precisamos instalar o gerenciador de versões do node (NVM), que permitirá instalar o node e o npm. Podemos instalar o nvm assim.</p><p><code>sudo curl https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash</code></p><p>Isso instalará o nvm, que podemos usar para instalar o node e o npm. Para fazer isso, basta listar as versões do node disponíveis para download e instalar a mais estável.</p><p>Comando para listar versões do node<br><code>nvm ls remote</code></p><p>Comando de instalação<br><code>nvm install version-of-node</code></p><p>Depois de instalar o npm e o node, se você tentar executar <code>npm install</code> no diretório do projeto, receberá um erro de permissão negada.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-63.png" class="kg-image" alt="image-63" width="600" height="400" loading="lazy"></figure><p>Você pode executar o comando abaixo para dar permissão de escrita no diretório. O comando abaixo dá muito mais do que apenas permissões de escrita, mas configurar permissões no Linux está fora do escopo deste tutorial.</p><p>Digite <code>sudo chmod 777</code> no diretório.</p><p>Aqui está um link para um tutorial se você quiser saber mais sobre o <a href="https://www.computerhope.com/unix/uchmod.htm">chmod</a> (em inglês). </p><p>Depois disso, seus módulos do npm devem instalar normalmente com o comando normal <code>npm install</code>.</p><p>Então, você pode simplesmente executar sua aplicação com o comando <code>npm start</code>, que iniciará seu servidor do node e servirá seu projeto do React como arquivos estáticos.</p><p>O problema é que o projeto só rodará nas portas não tradicionais, como 5000 ou 3000, ou qualquer porta que você estiver usando no <em>localhost</em>. Se você tentar a abordagem ingênua de apenas mudar a porta para a porta 80 no servidor, receberá um erro de permissão negada.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-64.png" class="kg-image" alt="image-64" width="600" height="400" loading="lazy"></figure><p>Para corrigir isso, usaremos o nginx.</p><h3 id="nginx">nginx</h3><p>Você pode estar se perguntando por que estamos usando nginx se já temos o node. É possível usar nginx como um servidor de http, mas usaremos o nginx como um proxy reverso, o que manterá o node como o servidor http real.</p><p>A configuração ficará assim.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-68.png" class="kg-image" alt="image-68" width="600" height="400" loading="lazy"></figure><p>Os benefícios de se fazer isso são:</p><ul><li>O nginx atua como um balanceador de carga em nível de aplicação</li><li>Ajuda o node com desempenho e confiabilidade</li><li>Melhora a segurança</li><li>Previne ataques DoS</li></ul><p>Aqui está um diagrama que mostra um proxy regular versus um proxy reverso.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-69.png" class="kg-image" alt="image-69" width="600" height="400" loading="lazy"></figure><p>Em um proxy regular, um <em>client </em>da web pode enviar e receber dados de vários servidores da web. Em um proxy reverso, um único servidor da web pode enviar e receber dados de vários <em>clients </em>da web.</p><p>Agora, vamos para a nossa instância do EC2 e vamos usar o ssh nela.</p><p>A primeira coisa que precisamos fazer é instalar o nginx. A Amazon Linux AMI 2 já vem com o nginx. Então, você pode instalar assim:</p><p><code>sudo amazon-linux-extras install nginx1.12</code></p><p>Depois, podemos acessar o diretório do nginx com <code>cd /etc/nginx</code></p><p>Podemos editar o arquivo de configuração do nginx com o comando <code>sudo nano nginx.conf</code></p><p>Isso abrirá o arquivo nginx.conf no editor sudo nano.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-65.png" class="kg-image" alt="image-65" width="600" height="400" loading="lazy"></figure><p>Podemos adicionar este código à rota de localização do home</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-66.png" class="kg-image" alt="image-66" width="600" height="400" loading="lazy"></figure><p>Basicamente, estamos dizendo para definir a build do react como a rota <em>root</em>. Defina o arquivo <em>index.html</em> como o índice principal. Finalmente, em cada solicitação subsequente, sirva o mesmo arquivo index.html.</p><p>Isso porque o React é uma aplicação de página única e, literalmente, um único arquivo html. Então, para possibilitar navegar dentro da aplicação do React, precisamos servir esse mesmo arquivo html novamente em caso de erros.</p><p>Em seguida, também podemos configurar o nginx para lidar com nossas rotas da API.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-67.png" class="kg-image" alt="image-67" width="600" height="400" loading="lazy"></figure><p>Isso é, na maior parte, código <em>boilerplate</em>, mas a propriedade a ser observada é o <code>proxy_pass</code>, que é nosso IP público e a porta não padrão.</p><p>Esse endereço IP será então enviado por proxy para a porta padrão 80, o que nos permitirá acessar o site normalmente.</p><p>Versão copiável do código:</p><pre><code>    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  localhost;


        # Carrega os arquivos de configuração para o bloco de servidor padrão.
        include /etc/nginx/default.d/*.conf;


        location /api/ {
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
                proxy_set_header X-NginX-Proxy true;
                proxy_pass http://10.0.1.187:3000;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection 'upgrade';
                proxy_set_header Host $host;
                proxy_cache_bypass $http_upgrade;

        }
</code></pre><p>Depois disso, basta salvar e sair do editor.</p><p>Também precisamos reiniciar o nginx para que as alterações tenham efeito. Fazemos isso com <code>sudo systemctl restart nginx</code>.</p><p>Isso é tudo de que você precisa fazer para ter o nginx como proxy reverso. Sua aplicação, agora, poderá rodar na porta 80 normalmente.</p><h3 id="pm2">PM2</h3><p>O PM2 é um gerenciador de clusters e nos permite rodar nossa aplicação automaticamente e também reiniciar automaticamente se ela travar.</p><p>Vamos nos conectar novamente à nossa instância via ssh e instalar o PM2</p><p><code>npm install pm2 -g</code></p><p>A flag -g é importante porque instala o PM2 globalmente. Isso é crucial, porque é isso que permite que o PM2 faça seu trabalho.</p><p>Se pensar a respeito, se o PM2 fosse instalado localmente, ele travaria quando nossa aplicação travasse. Ou seja, não daria certo. Instalamos globalmente para que ele fique fora do nosso projeto e possa reiniciar o projeto se ele travar.</p><p>Você pode rodar o PM2 no seu projeto com <code>pm2 start app.js -i max</code></p><p>Isso iniciará o projeto com o número máximo de núcleos. Isso é importante porque o node é <em>single threaded</em> e usar todos os núcleos maximiza o desempenho.</p><p>Se feito com sucesso, você deve ver uma página que se parece com esta.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-70.png" class="kg-image" alt="image-70" width="600" height="400" loading="lazy"></figure><p>Aqui estão alguns outros comandos úteis para o PM2</p><p><code>pm2 list</code>: lista todos os processos em execução</p><p><code>pm2 stop app 0</code>: para a aplicação com id 0</p><p><code>pm2 delete app 0</code>: exclui a aplicação com id 0</p><p><code>pm2 restart app 0</code>: reinicia a aplicação com id 0</p><p><code>pm2 start app.js -i max</code>: inicia app.js com o número máximo de threads disponíveis</p><p>É isso! Obrigado pela leitura e parabéns se você leu todo o tutorial – isso não é uma tarefa fácil.</p><blockquote>Conecte-se com o autor no <a href="https://twitter.com/iqbal125sf">Twitter</a> para mais atualizações sobre futuros tutoriais.</blockquote> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como criar uma aplicação de previsão do tempo com React e React Hooks ]]>
                </title>
                <description>
                    <![CDATA[ O React é uma biblioteca de front-end incrível que você pode usar para criar interfaces de usuário. Uma das melhores coisas sobre o React é que os componentes que criamos são encapsulados. Em outras palavras, eles não podem ser vistos. Vamos aprender mais sobre como tudo isso funciona criando uma ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-criar-uma-aplicacao-de-previsao-do-tempo-com-react-e-react-hooks/</link>
                <guid isPermaLink="false">66cf6349fc5d380414effe7c</guid>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Daniel Rosa ]]>
                </dc:creator>
                <pubDate>Wed, 28 Aug 2024 18:30:32 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2024/08/Pink-Cute-Chic-Vintage-90s-Virtual-Trivia-Quiz-Presentations--39-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/learn-react-by-building-a-weather-app/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Build a Weather Application with React and React Hooks</a>
      </p><p>O React é uma biblioteca de <em>front-end</em> incrível que você pode usar para criar interfaces de usuário.</p><p>Uma das melhores coisas sobre o React é que os componentes que criamos são encapsulados. Em outras palavras, eles não podem ser vistos.</p><p>Vamos aprender mais sobre como tudo isso funciona criando uma aplicação de previsão do tempo usando o React.</p><h2 id="como-instalar-o-node-e-o-npm">Como instalar o Node e o npm</h2><p>Para criar nossa aplicação em React, precisamos de um ambiente de tempo de execução chamado Node. Ele é principalmente usado para executar código JavaScript.</p><p>Para baixá-lo, vá para <a href="https://nodejs.org/en/">https://nodejs.org/en/</a>.</p><p>Você também precisará do <strong>npm</strong>, que é um gerenciador de pacotes utilizado no Node. Você pode usá-lo para instalar pacotes para suas aplicações em JavaScript. Felizmente, ele vem com o Node. Então, você não precisa baixá-lo separadamente.</p><p>Uma vez que os dois estejam instalados, abra seu terminal ou prompt de comando e digite <code>node -v</code>. Isso verifica qual versão do Node você tem.</p><h2 id="como-criar-uma-aplica-o-em-react">Como criar uma aplicação em React</h2><p>Para criar nossa aplicação em React, digite <strong><code>npx create-react-app &lt;nome do seu app&gt;</code></strong> no seu terminal, ou <strong><code>npx create-react-app my-weather-app</code></strong>, neste caso.</p><p>Você verá que os pacotes estão sendo instalados.</p><p>Uma vez que os pacotes estiverem prontos, entre na pasta do projeto e digite <strong><code>npm start</code></strong>.</p><p>Você verá o <em>template </em>padrão do <code>create-react-app</code> para o React, assim:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screenshot-2021-03-12-12-07-22.png" class="kg-image" alt="Screenshot-2021-03-12-12-07-22" width="600" height="400" loading="lazy"><figcaption>O <em>template</em> padrão do <em>boilerplate</em> do React</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screenshot-2021-03-12-12-08-28.png" class="kg-image" alt="Screenshot-2021-03-12-12-08-28" width="600" height="400" loading="lazy"><figcaption>App.js</figcaption></figure><p>Não precisamos de tudo isso agora. Então, vamos limpar um pouco do código.</p><p>No seu arquivo <strong>app.js</strong>, limpe tudo dentro da tag <code>div</code>. Remova a importação do logo.</p><p>Você receberá uma tela em branco na saída depois de fazer isso.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screenshot-2021-03-12-12-12-25.png" class="kg-image" alt="Screenshot-2021-03-12-12-12-25" width="600" height="400" loading="lazy"><figcaption>App.js após a limpeza</figcaption></figure><h2 id="como-instalar-os-pacotes-necess-rios">Como instalar os pacotes necessários</h2><p>Para tornar essa aplicação mais atraente, precisamos de alguns pacotes externos. Então, vamos instalá-los.</p><p>Precisamos da biblioteca <a href="https://react.semantic-ui.com/usage/">Semantic UI React</a>. Para instalá-la, digite o seguinte comando no terminal:</p><pre><code class="language-bash">npm install semantic-ui-react semantic-ui-css
</code></pre><p>Uma vez instalada, abra <strong>index.js</strong> e importe a biblioteca. Apenas copie e cole o seguinte comando no seu arquivo <strong>index.js</strong>:</p><pre><code>import 'semantic-ui-css/semantic.min.css'
</code></pre><p>Também precisamos do <a href="https://momentjs.com/">moment.js</a> para formatar o horário e data. Instale-o usando o seguinte comando:</p><pre><code>npm install moment --save
</code></pre><p>Você pode verificar seu arquivo <code>package.json</code> para acompanhar todos os pacotes instalados.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screenshot-2021-03-12-12-21-01.png" class="kg-image" alt="Screenshot-2021-03-12-12-21-01" width="600" height="400" loading="lazy"><figcaption>package.json</figcaption></figure><p>Aqui, você pode ver todos os pacotes que possui até agora.</p><h2 id="como-criar-nossa-aplica-o-de-previs-o-do-tempo">Como criar nossa aplicação de previsão do tempo</h2><p>Para fazer nossa aplicação de previsão do tempo funcionar, precisamos do OpenWeatherMap, uma API de terceiros que nos permitirá buscar os dados do clima.</p><p>Acesse <a href="https://home.openweathermap.org/users/sign_up">https://home.openweathermap.org/users/sign_up</a> e crie sua própria conta.</p><p>Após finalizar, clique na opção <strong>API</strong>, na barra de navegação. Você verá diferentes opções como <em>Current Weather Data </em>(Dados meteorológicos atuais), <em>Hourly Forecast 4 days</em> (Previsões de hora em hora para 4 dias), <em>Daily Forecast 16 days</em> (Previsões diárias para 16 dias), entre outras. Esses são <em>endpoints</em> da API dos quais você precisará para buscar os dados.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screenshot-2021-03-12-12-30-10.png" class="kg-image" alt="Screenshot-2021-03-12-12-30-10" width="600" height="400" loading="lazy"></figure><p>Você também precisa de uma chave de API para chamar essas APIs. Para obter sua chave de API, clique em seu nome de usuário no canto superior direito, e depois em "<em>My API keys</em>" (minhas chaves de API).</p><p>Crie uma chave de API, se ela ainda não existir.</p><p>Na sua pasta principal da aplicação, crie um arquivo chamado <strong>.env.</strong></p><p>Esse é um arquivo de variáveis de ambiente, que conterá todos os seus <em>endpoints </em>e chaves de API.</p><pre><code>REACT_APP_API_URL = 'https://api.openweathermap.org/data/2.5'
REACT_APP_API_KEY = (Cole sua chave de API aqui)
REACT_APP_ICON_URL = 'https://openweathermap.org/img/w'
</code></pre><p>Cole sua chave API copiada na variável REACT_APP_API_KEY.</p><h2 id="como-usar-os-react-hooks">Como usar os React Hooks</h2><p>Os React Hooks nos permitem usar e gerenciar o <em>state </em>(em português, estado) em nossos componentes funcionais.</p><p>Vamos usar os <em>hooks</em> <code>useState</code> e <code>useEffect</code>. Vamos importá-los no topo.</p><pre><code>import React, { useEffect, useState } from "react";
</code></pre><p>Vamos criar dois <em>states</em>, um para latitude e outro para longitude.</p><pre><code>const [lat, setLat] = useState([]);
const [long, setLong] = useState([]);
</code></pre><p>Agora, crie a função <code>useEffect</code>. Seu objetivo é carregar as funções quando a aplicação for carregada e recarregada.</p><pre><code>useEffect(() =&gt; {
    navigator.geolocation.getCurrentPosition(function(position) {
      setLat(position.coords.latitude);
      setLong(position.coords.longitude);
    });

    console.log("A latitude é:", lat)
    console.log("A longitude é:", long)
  }, [lat, long]);
</code></pre><p>Obtivemos nossa latitude e longitude usando <code>navigator.geolocation</code> e usamos <strong><strong>setLong</strong> </strong>e <strong><strong>setLat</strong> </strong>para definir os <em>states </em>de longitude e de latitude.</p><figure class="kg-card kg-code-card"><pre><code class="language-import">import React, { useEffect, useState } from "react";
export default function App() {

  const [lat, setLat] = useState([]);
  const [long, setLong] = useState([]);

  useEffect(() =&gt; {
    navigator.geolocation.getCurrentPosition(function(position) {
      setLat(position.coords.latitude);
      setLong(position.coords.longitude);
    });

    console.log("Latitude is:", lat)
    console.log("Longitude is:", long)
  }, [lat, long]);

  return (
    &lt;div className="App"&gt;

    &lt;/div&gt;
  );
}
</code></pre><figcaption>app.js</figcaption></figure><p>Nosso arquivo app.js está assim agora. Você pode verificar o console para os valores de latitude e longitude.</p><figure class="kg-card kg-code-card"><pre><code>A latitude é: 25.5922166
A longitude é: 85.12761069999999</code></pre><figcaption>Nossa latitude e longitude</figcaption></figure><h2 id="como-obter-nossa-localiza-o-atual-usando-a-latitude-e-a-longitude">Como obter nossa localização atual usando a latitude e a longitude</h2><p>Vamos criar outra função <strong>getWeather</strong>, que buscará os dados meteorológicos da Weather API, com base em nossa latitude e longitude.</p><p>Nessa função, estamos usando uma chamada de <em>fetch </em>para obter os dados da API. <strong>process.env.REACT_APP_API_URL</strong> obtém o endereço da sua API e <strong>process.env.REACT_APP_API_KEY</strong> obtém sua chave de API do arquivo <strong>.env</strong>. <code>lat</code> e <code>long</code> são a latitude e longitude que obtivemos anteriormente.</p><p>Então, convertemos os dados para o formato <strong>JSON</strong>.</p><p>No próximo passo, usamos <strong>setData</strong> para armazenar nosso resultado no objeto <strong>data</strong>.</p><pre><code>await fetch(`${process.env.REACT_APP_API_URL}/weather/?lat=${lat}&amp;lon=${long}&amp;units=metric&amp;APPID=${process.env.REACT_APP_API_KEY}`)
      .then(res =&gt; res.json())
      .then(result =&gt; {
        setData(result)
        console.log(result);
      });
</code></pre><p>Depois, registramos os dados no console.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screenshot-2021-03-12-13-36-26.png" class="kg-image" alt="Screenshot-2021-03-12-13-36-26" width="600" height="400" loading="lazy"></figure><p>Aqui, você pode ver todos os dados meteorológicos com base em nossa latitude e longitude.</p><p>Este é o nosso novo arquivo app.js, que busca os dados meteorológicos com base na longitude e na latitude:</p><figure class="kg-card kg-code-card"><pre><code>import './App.css';
import React, { useEffect, useState } from "react";
import Weather from './components/weather';
export default function App() {
  
  const [lat, setLat] = useState([]);
  const [long, setLong] = useState([]);
  const [data, setData] = useState([]);

  useEffect(() =&gt; {
    const fetchData = async () =&gt; {
      navigator.geolocation.getCurrentPosition(function(position) {
        setLat(position.coords.latitude);
        setLong(position.coords.longitude);
      });

      await fetch(`${process.env.REACT_APP_API_URL}/weather/?lat=${lat}&amp;lon=${long}&amp;units=metric&amp;APPID=${process.env.REACT_APP_API_KEY}`)
      .then(res =&gt; res.json())
      .then(result =&gt; {
        setData(result)
        console.log(result);
      });
    }
    fetchData();
  }, [lat,long])
  
  return (
    &lt;div className="App"&gt;
      
    &lt;/div&gt;
  );
}
</code></pre><figcaption>app.js</figcaption></figure><h3 id="como-criar-os-componentes-meteorol-gicos">Como criar os componentes meteorológicos</h3><p>Vamos criar nossos componentes meteorológicos (Weather), onde exibiremos nossos dados meteorológicos.</p><p>Na sua pasta <strong>src</strong>, crie uma pasta chamada <strong>components</strong>. Nela, crie um arquivo chamado <strong>weather.js.</strong></p><p>Agora, vamos chamar nosso componente meteorológico em nosso arquivo principal <strong>app.js.</strong></p><figure class="kg-card kg-code-card"><pre><code>import './App.css';
import React, { useEffect, useState } from "react";
import Weather from './components/weather';
export default function App() {
  
  const [lat, setLat] = useState([]);
  const [long, setLong] = useState([]);
  const [data, setData] = useState([]);

  useEffect(() =&gt; {
    const fetchData = async () =&gt; {
      navigator.geolocation.getCurrentPosition(function(position) {
        setLat(position.coords.latitude);
        setLong(position.coords.longitude);
      });

      await fetch(`${process.env.REACT_APP_API_URL}/weather/?lat=${lat}&amp;lon=${long}&amp;units=metric&amp;APPID=${process.env.REACT_APP_API_KEY}`)
      .then(res =&gt; res.json())
      .then(result =&gt; {
        setData(result)
        console.log(result);
      });
    }
    fetchData();
  }, [lat,long])
  
  return (
    &lt;div className="App"&gt;
      {(typeof data.main != 'undefined') ? (
        &lt;Weather weatherData={data}/&gt;
      ): (
        &lt;div&gt;&lt;/div&gt;
      )}
      
    &lt;/div&gt;
  );
}
</code></pre><figcaption>Importando o componente Weather no arquivo app.js</figcaption></figure><p>Você pode ver que incluí uma verificação na instrução de retorno. Se o tipo de dados que estamos obtendo for <code>undefined</code>, ele nos mostrará uma div vazia. Como a busca de dados é uma função async, é obrigatório incluir essa verificação. Ela carrega a função após todas as outras funções terem sido executadas. Então, se você remover essa verificação, receberá um erro.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screenshot-2021-03-13-05-19-29-1.png" class="kg-image" alt="Screenshot-2021-03-13-05-19-29-1" width="600" height="400" loading="lazy"></figure><p>Isso ocorre porque nossa aplicação renderiza a instrução de retorno antes que a chamada à API seja feita. Não há nada para mostrar nesse caso. Então, ela lança um erro indefinido.</p><p>Para saber mais sobre async/await, confira <a href="https://www.freecodecamp.org/news/async-await-in-javascript/">este artigo</a> (texto em inglês).</p><h3 id="como-criar-o-corpo-do-nosso-componente-weather">Como criar o corpo do nosso componente Weather</h3><p>Para esta parte, vamos usar a biblioteca Semantic UI para projetar nossa interface.</p><p>Vamos criar um <em>card</em>, que exibirá nossas informações meteorológicas.</p><figure class="kg-card kg-code-card"><pre><code>import React from 'react';
import './styles.css';
import { Card } from 'semantic-ui-react'

const CardExampleCard = ({weatherData}) =&gt; (
  &lt;Card&gt;
    &lt;Card.Content&gt;
        &lt;Card.Header className="header"&gt;{weatherData.name}&lt;/Card.Header&gt;
    &lt;/Card.Content&gt;
  &lt;/Card&gt;
)

export default CardExampleCard;
</code></pre><figcaption>Weather.js</figcaption></figure><p>Aqui, importamos um <em>card</em> do semantic-ui-react e, dentro dele, um cabeçalho que mostrará o nome da sua cidade.</p><p>A questão é: como obtemos dados do nosso app.js para o componente weather.js?</p><p>A resposta é simples. Podemos usar <em>props </em>no React para enviar dados de um componente pai para um componente filho. No nosso caso, nosso componente pai é o app.js e nosso componente filho é o weather.js.</p><p>Para fazer isso, basta adicionar as props no componente em <strong>app.js.</strong></p><pre><code>&lt;Weather weatherData={data}/&gt;
</code></pre><p>Aqui, estamos passando os dados com o nome da <em>prop </em>como weatherData. Receberemos as <em>props </em>weatherData em <strong>Weather.js.</strong></p><pre><code>import React from 'react';
import './styles.css';
import { Card } from 'semantic-ui-react'

const CardExampleCard = ({weatherData}) =&gt; (
  &lt;Card&gt;
    &lt;Card.Content&gt;
        &lt;Card.Header className="header"&gt;{weatherData.name}&lt;/Card.Header&gt;
    &lt;/Card.Content&gt;
  &lt;/Card&gt;
)

export default CardExampleCard;
</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screenshot-2021-03-12-17-36-56.png" class="kg-image" alt="Screenshot-2021-03-12-17-36-56" width="600" height="400" loading="lazy"></figure><p>Você pode ver que obtivemos o nome da cidade de acordo com a localização.</p><p>Da mesma maneira, podemos adicionar mais campos ao nosso componente de previsão do tempo.</p><pre><code>import React from 'react';
import './styles.css';
import { Card } from 'semantic-ui-react'

const CardExampleCard = ({weatherData}) =&gt; (
  &lt;Card&gt;
    &lt;Card.Content&gt;
        &lt;Card.Header className="header"&gt;Nome da Cidade: {weatherData.name}&lt;/Card.Header&gt;
        &lt;p&gt;Temperatura: {weatherData.main.temp}&lt;/p&gt;
        &lt;p&gt;Nascer do Sol: {weatherData.sys.sunrise}&lt;/p&gt;
        &lt;p&gt;Pôr do Sol: {weatherData.sys.sunset}&lt;/p&gt;
        &lt;p&gt;Descrição: {weatherData.weather[0].description}&lt;/p&gt;
    &lt;/Card.Content&gt;
  &lt;/Card&gt;
)

export default CardExampleCard;
</code></pre><p>Podemos obter a temperatura, o horário do nascer do sol, do pôr do sol e a descrição do clima atual da API.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screenshot-2021-03-12-17-45-36-1.png" class="kg-image" alt="Screenshot-2021-03-12-17-45-36-1" width="600" height="400" loading="lazy"></figure><p>Você pode adicionar quaisquer outros campos que desejar, como umidade, velocidade do vento, visibilidade e mais.</p><h3 id="como-formatar-os-dados-e-adicionar-o-dia-e-a-data-de-hoje">Como formatar os dados e adicionar o dia e a data de hoje</h3><p>Vamos formatar os dados para que sejam fáceis de entender. Vamos adicionar mais alguns campos.</p><p>Para começar, adicione a unidade de temperatura. Você pode fazer isso adicionando <strong>&amp;deg;C</strong> após a temperatura.</p><p>Além disso, vamos mudar o horário do nascer e pôr do sol para a hora local.</p><pre><code>import React from 'react';
import './styles.css';
import { Card } from 'semantic-ui-react'

const CardExampleCard = ({weatherData}) =&gt; (
  &lt;Card&gt;
    &lt;Card.Content&gt;
        &lt;Card.Header className="header"&gt;Nome da Cidade: {weatherData.name}&lt;/Card.Header&gt;
        &lt;p&gt;Temperatura: {weatherData.main.temp} &amp;deg;C&lt;/p&gt;
        &lt;p&gt;Nascer do Sol: {new Date(weatherData.sys.sunrise * 1000).toLocaleTimeString('en-IN')}&lt;/p&gt;
        &lt;p&gt;Pôr do Sol: {new Date(weatherData.sys.sunset * 1000).toLocaleTimeString('en-IN')}&lt;/p&gt;
        &lt;p&gt;Descrição: {weatherData.weather[0].main}&lt;/p&gt;
        &lt;p&gt;Umidade: {weatherData.main.humidity} %&lt;/p&gt;
    &lt;/Card.Content&gt;
  &lt;/Card&gt;
)

export default CardExampleCard;
</code></pre><p>Agora, vamos adicionar o dia e a data de hoje usando o <strong>moment.js.</strong></p><figure class="kg-card kg-code-card"><pre><code>import moment from 'moment';

&lt;p&gt;Dia: {moment().format('dddd')}&lt;/p&gt;
&lt;p&gt;Data: {moment().format('LL')}&lt;/p&gt;
</code></pre><figcaption>Usando o moment.js</figcaption></figure><p>Importamos o pacote do <strong>moment</strong> no topo e exibimos o dia e a data de hoje, respectivamente. A grande coisa sobre este pacote é que ele atualiza automaticamente a data e o dia.</p><p>É assim que nosso <strong>weather.js</strong> se parece agora:</p><figure class="kg-card kg-code-card"><pre><code>import React from 'react';
import './styles.css';
import { Card } from 'semantic-ui-react';
import moment from 'moment';

const CardExampleCard = ({weatherData}) =&gt; (
  &lt;Card&gt;
    &lt;Card.Content&gt;
        &lt;Card.Header className="header"&gt;Nome da Cidade: {weatherData.name}&lt;/Card.Header&gt;
        &lt;p&gt;Temperatura: {weatherData.main.temp} &amp;deg;C&lt;/p&gt;
        &lt;p&gt;Nascer do Sol: {new Date(weatherData.sys.sunrise * 1000).toLocaleTimeString('en-IN')}&lt;/p&gt;
        &lt;p&gt;Pôr do Sol: {new Date(weatherData.sys.sunset * 1000).toLocaleTimeString('en-IN')}&lt;/p&gt;
        &lt;p&gt;Descrição: {weatherData.weather[0].main}&lt;/p&gt;
        &lt;p&gt;Umidade: {weatherData.main.humidity} %&lt;/p&gt;
        &lt;p&gt;Dia: {moment().format('dddd')}&lt;/p&gt;
        &lt;p&gt;Data: {moment().format('LL')}&lt;/p&gt;
    &lt;/Card.Content&gt;
  &lt;/Card&gt;
)

export default CardExampleCard;
</code></pre><figcaption>weather.js</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screenshot-2021-03-13-12-16-14.png" class="kg-image" alt="Screenshot-2021-03-13-12-16-14" width="600" height="400" loading="lazy"><figcaption>Este é o nosso resultado.</figcaption></figure><h2 id="vamos-estilizar">Vamos estilizar</h2><p>Agora que temos todos os nossos dados, vamos estilizá-los para torná-los mais atraentes.</p><p>Primeiramente, vamos tornar o <em>card</em> maior, mudar o <code>border-radius</code>, adicionar uma fonte mais legal, uma cor e remover o alinhamento de texto.</p><figure class="kg-card kg-code-card"><pre><code>import React from 'react';
import './styles.css';
import moment from 'moment';

const CardExampleCard = ({weatherData}) =&gt; (
  &lt;div className="main"&gt;
      &lt;p className="header"&gt;{weatherData.name}&lt;/p&gt;
      &lt;div&gt;
        &lt;p className="day"&gt;Dia: {moment().format('dddd')}&lt;/p&gt;
      &lt;/div&gt;

      &lt;div&gt;
        &lt;p className="temp"&gt;Temperatura: {weatherData.main.temp} &amp;deg;C&lt;/p&gt;
      &lt;/div&gt;
      
  &lt;/div&gt;
)

export default CardExampleCard;
</code></pre><figcaption>weather.js</figcaption></figure><figure class="kg-card kg-code-card"><pre><code>
@import url('https://fonts.googleapis.com/css2?family=Recursive&amp;display=swap');

.main{
    width: 700px;
    border-radius: 15px;
    background-color: #01579b;
}

.header{
    background-color: #424242;
    color: whitesmoke;
    padding: 10px;
    font-size: 28px;
    border-radius: 15px;
    font-family: 'Recursive', sans-serif;
}

.day{
    padding: 15px;
    color: whitesmoke;
    font-family: 'Recursive', sans-serif;
    font-size: 24px;
    font-weight: 600;
}

.temp{
    padding: 15px;
    color: whitesmoke;
    font-family: 'Recursive', sans-serif;
    font-size: 18px;
}</code></pre><figcaption>styles.css</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screenshot-2021-03-13-12-48-03.png" class="kg-image" alt="Screenshot-2021-03-13-12-48-03" width="600" height="400" loading="lazy"><figcaption>Esta é a aparência da nossa aplicação agora.</figcaption></figure><p>Vamos usar o <strong>flexbox</strong> para organizar os dados em colunas.</p><pre><code class="language-jsx">&lt;div className="flex"&gt;
   &lt;p className="day"&gt;Dia: {moment().format('dddd')}&lt;/p&gt;
&lt;/div&gt;

&lt;div className="flex"&gt;
   &lt;p className="temp"&gt;Temperatura: {weatherData.main.temp} &amp;deg;C&lt;/p&gt;
&lt;/div&gt;
</code></pre><p>Nomeie as divs como 'flex' e adicione a seguinte propriedade no <strong><em>styles.css.</em></strong></p><pre><code class="language-css">.flex{
    display: flex;
    justify-content: space-between;
}
</code></pre><p>Nosso weather.js agora ficará assim.</p><figure class="kg-card kg-code-card"><pre><code class="language-jsx">import React from 'react';
import './styles.css';
import moment from 'moment';

const CardExampleCard = ({weatherData}) =&gt; (
  &lt;div className="main"&gt;
      &lt;p className="header"&gt;{weatherData.name}&lt;/p&gt;
      &lt;div className="flex"&gt;
        &lt;p className="day"&gt;Dia: {moment().format('dddd')}&lt;/p&gt;
        &lt;p className="day"&gt;{moment().format('LL')}&lt;/p&gt;
      &lt;/div&gt;

      &lt;div className="flex"&gt;
        &lt;p className="temp"&gt;Temperatura: {weatherData.main.temp} &amp;deg;C&lt;/p&gt;
        &lt;p className="temp"&gt;Umidade: {weatherData.main.humidity} %&lt;/p&gt;
      &lt;/div&gt;
      
      
  &lt;/div&gt;
)

export default CardExampleCard;
</code></pre><figcaption>weather.js</figcaption></figure><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screenshot-2021-03-13-12-56-27.png" class="kg-image" alt="Screenshot-2021-03-13-12-56-27" width="600" height="400" loading="lazy"></figure><p>Do mesmo modo, adicione os campos restantes.</p><figure class="kg-card kg-code-card"><pre><code class="language-jsx">import React from 'react';
import './styles.css';
import moment from 'moment';

const WeatherCard = ({weatherData}) =&gt; (
  &lt;div className="main"&gt;
      &lt;p className="header"&gt;{weatherData.name}&lt;/p&gt;
      &lt;div className="flex"&gt;
        &lt;p className="day"&gt;{moment().format('dddd')}, &lt;span&gt;{moment().format('LL')}&lt;/span&gt;&lt;/p&gt;
        &lt;p className="description"&gt;{weatherData.weather[0].main}&lt;/p&gt;
      &lt;/div&gt;

      &lt;div className="flex"&gt;
        &lt;p className="temp"&gt;Temperatura: {weatherData.main.temp} &amp;deg;C&lt;/p&gt;
        &lt;p className="temp"&gt;Umidade: {weatherData.main.humidity} %&lt;/p&gt;
      &lt;/div&gt;

      &lt;div className="flex"&gt;
        &lt;p className="sunrise-sunset"&gt;Nascer do sol: {new Date(weatherData.sys.sunrise * 1000).toLocaleTimeString('en-IN')}&lt;/p&gt;
        &lt;p className="sunrise-sunset"&gt;Pôr do sol: {new Date(weatherData.sys.sunset * 1000).toLocaleTimeString('en-IN')}&lt;/p&gt;
      &lt;/div&gt;
    
  &lt;/div&gt;
)

export default WeatherCard;
</code></pre><figcaption>weather.js</figcaption></figure><figure class="kg-card kg-code-card"><pre><code class="language-css">@import url('https://fonts.googleapis.com/css2?family=Recursive&amp;display=swap');

.main{
    width: 700px;
    border-radius: 20px;
    background-color: #01579b;
}

.top{
    height: 60px;
    background-color: #424242;
    color: whitesmoke;
    padding: 10px;
    border-radius: 20px 20px 0 0;
    font-family: 'Recursive', sans-serif;
    display: flex;
    justify-content: space-between;
}

.header{
    background-color: #424242;
    color: whitesmoke;
    margin: 10px 0px 0px 10px;
    font-size: 25px;
    border-radius: 20px 20px 0 0;
    font-family: 'Recursive', sans-serif;
}

.day{
    padding: 15px;
    color: whitesmoke;
    font-family: 'Recursive', sans-serif;
    font-size: 24px;
    font-weight: 600;
}

.temp{
    padding: 15px;
    color: whitesmoke;
    font-family: 'Recursive', sans-serif;
    font-size: 18px;
}

.flex{
    display: flex;
    justify-content: space-between;
}

.sunrise-sunset{
    padding: 15px;
    color: whitesmoke;
    font-family: 'Recursive', sans-serif;
    font-size: 16px;
}

.description{
    padding: 15px;
    color: whitesmoke;
    font-family: 'Recursive', sans-serif;
    font-size: 24px;
    font-weight: 600;
}
</code></pre><figcaption>styles.css</figcaption></figure><p>Esta é a aparência da nossa aplicação agora:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screenshot-2021-03-13-13-37-46.png" class="kg-image" alt="Screenshot-2021-03-13-13-37-46" width="600" height="400" loading="lazy"></figure><h3 id="como-adicionar-um-bot-o-de-atualizar">Como adicionar um botão de atualizar</h3><p>Vamos adicionar um botão de atualizar na parte superior da nossa página.</p><figure class="kg-card kg-code-card"><pre><code class="language-jsx">import React from 'react';
import './styles.css';
import moment from 'moment';
import { Button } from 'semantic-ui-react';

const refresh = () =&gt; {
  window.location.reload();
}

const WeatherCard = ({weatherData}) =&gt; (
  &lt;div className="main"&gt;

      &lt;div className="top"&gt;
        &lt;p className="header"&gt;{weatherData.name}&lt;/p&gt;
        &lt;Button className="button" inverted color='blue' circular icon='refresh' onClick={refresh} /&gt;
      &lt;/div&gt;
      &lt;div className="flex"&gt;
        &lt;p className="day"&gt;{moment().format('dddd')}, &lt;span&gt;{moment().format('LL')}&lt;/span&gt;&lt;/p&gt;
        &lt;p className="description"&gt;{weatherData.weather[0].main}&lt;/p&gt;
      &lt;/div&gt;

      &lt;div className="flex"&gt;
        &lt;p className="temp"&gt;Temperatura: {weatherData.main.temp} &amp;deg;C&lt;/p&gt;
        &lt;p className="temp"&gt;Umidade: {weatherData.main.humidity} %&lt;/p&gt;
      &lt;/div&gt;
 )
 
 export default WeatherCard;
</code></pre><figcaption>weather.js</figcaption></figure><figure class="kg-card kg-code-card"><pre><code>.button {
  width: 35px;
  height: 35px;
}</code></pre><figcaption>styles.css</figcaption></figure><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screenshot-2021-03-13-13-51-37.png" class="kg-image" alt="Screenshot-2021-03-13-13-51-37" width="600" height="400" loading="lazy"></figure><p>Você pode ver um botão que acionará a função de atualização. Quando você pressioná-lo, ele atualizará a página.</p><h3 id="como-adicionar-um-carregador-quando-nossa-aplica-o-est-carregando">Como adicionar um carregador quando nossa aplicação está carregando</h3><p>Vamos adicionar um carregador (em inglês, <em>loader</em>) para tornar a aplicação ainda mais incrível.</p><p>Importe Loader da Semantic UI e adicione-o na função de retorno, onde verificamos se há dados <code>undefined</code>.</p><figure class="kg-card kg-code-card"><pre><code>import { Dimmer, Loader } from 'semantic-ui-react';

&lt;div className="App"&gt;
      {(typeof data.main != 'undefined') ? (
        &lt;Weather weatherData={data}/&gt;
      ): (
        &lt;div&gt;
          &lt;Dimmer active&gt;
            &lt;Loader&gt;Carregando..&lt;/Loader&gt;
          &lt;/Dimmer&gt;
       &lt;/div&gt;
     )}
 &lt;/div&gt;</code></pre><figcaption>app.js</figcaption></figure><h2 id="vamos-recapitular-o-que-fizemos">Vamos recapitular o que fizemos</h2><p>Criamos uma aplicação em React que mostra o clima atual com base na sua localização.</p><p>Vamos passar por tudo que fizemos até agora.</p><h3 id="aprendemos-sobre-state-e-props">Aprendemos sobre state e props</h3><p><em>State</em> e <em>Props</em> são recursos muito poderosos em React. Eles são usados para gerenciar dados e controlar seu fluxo dentro de diferentes componentes.</p><p>Em nossa aplicação, estamos gerenciando o <em>state</em>, que é o estado da aplicação. Por exemplo, o nome da cidade, a temperatura, a data, a umidade e tudo mais. Eles variam de usuário para usuário, dependendo de sua localização.</p><p><em>Props</em>, por outro lado, são usadas para passar dados entre componentes. Estamos obtendo os dados no nosso arquivo <strong>app.js</strong>, mas os estamos lendo no <strong>weather.js.</strong> Lembre-se, <em>props</em> só podem ser usadas para passar dados do componente pai para o componente filho.</p><h3 id="usamos-react-hooks">Usamos React Hooks</h3><p>Se você já usou componentes de classe, deve conhecer os métodos do ciclo de vida. Se não, eles são os métodos que são chamados quando nossa página renderiza ou re-renderiza. Não podemos, porém, usar métodos do ciclo de vida em componentes funcionais, pois eles são especialmente construídos para componentes de classe.</p><p>Os React Hooks são a alternativa. Usamos dois <em>hooks </em>em nossa aplicação. Um é o <code>useState</code>, usado para gerenciar o <em>state</em> da aplicação. O outro é o <code>useEffect</code>, que é carregado quando a página é renderizada ou carregada.</p><h3 id="experimentamos-a-semantic-ui">Experimentamos a Semantic UI</h3><p>A Semantic UI é uma biblioteca para React que possui componentes pré-definidos incríveis.</p><p>Isso é tudo, pessoal. Você pode adicionar mais recursos à aplicação, como uma previsão de cinco dias, ícones e muito mais.</p><p>Você pode <a href="https://github.com/nishant-666/React-weather">encontrar o código no Github</a> se quiser experimentar mais.</p><p>Você também pode <a href="https://youtu.be/Y1wKWIRNthQ">assistir a este tutorial no canal do YouTube do autor</a> (em inglês), se quiser.</p><blockquote>Experimente sempre mais e mais. Bons estudos para você.</blockquote> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ React Testing Library – tutorial com exemplos de código em JavaScript ]]>
                </title>
                <description>
                    <![CDATA[ Este artigo ajudará você a aprender o que é a React Testing Library e como você pode usá-la para testar sua aplicação em React. Este tutorial assumirá que você já conhece um pouco de JavaScript básico e que entende os fundamentos de como o React funciona. A React Testing Library ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/react-testing-library-tutorial-com-exemplos-de-codigo-em-javascript/</link>
                <guid isPermaLink="false">66801a5223266d03fc8b7f62</guid>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kris Lagerström ]]>
                </dc:creator>
                <pubDate>Mon, 08 Jul 2024 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2024/07/react-testing-library-guide-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/react-testing-library-tutorial-javascript-example-code/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">React Testing Library – Tutorial with JavaScript Code Examples</a>
      </p><p>Este artigo ajudará você a aprender o que é a <em>React Testing Library</em> e como você pode usá-la para testar sua aplicação em React.</p><p>Este tutorial assumirá que você já conhece um pouco de JavaScript básico e que entende os fundamentos de como o React funciona.</p><p>A <a href="https://testing-library.com/docs/react-testing-library/intro">React Testing Library</a> é uma ferramenta utilitária de teste, construída para testar a árvore real do DOM renderizada pelo React no navegador. O objetivo da biblioteca é ajudá-lo a escrever testes que se assemelhem ao modo como um usuário utilizaria a aplicação. Ela pode dar a você mais confiança de que sua aplicação funciona como esperado quando um usuário real a utiliza.</p><p>A biblioteca faz isso fornecendo métodos utilitários que consultarão o DOM da mesma maneira que um usuário faria. Por exemplo, se um usuário encontrasse um botão para 'Salvar' seu trabalho em texto, a biblioteca forneceria a você o método <code>getByText()</code>. Você vai aprender mais sobre os métodos da biblioteca para testar mais tarde.</p><p>Primeiramente, porém, vamos ver um exemplo da React Testing Library em ação.</p><h2 id="como-usar-a-react-testing-library">Como usar a React Testing Library</h2><p>Uma aplicação React criada com Create React App (ou CRA) já inclui tanto a React Testing Library quanto o Jest por padrão. Então, tudo o que você precisa fazer é escrever seu código de teste.</p><p>Se você quiser usar a React Testing Library fora de uma aplicação do CRA, precisa instalar tanto a React Testing Library quanto o Jest manualmente com o NPM:</p><pre><code class="language-shell">npm install --save-dev @testing-library/react jest</code></pre><h3 id="instalando-a-react-testing-library-e-o-jest">Instalando a React Testing Library e o Jest</h3><p>Você precisa instalar o Jest porque a React Testing Library apenas fornece métodos para ajudar você a escrever os scripts de teste. Desse modo, você ainda precisa de um <em>framework</em> de teste do JavaScript para executar o código de teste.</p><p>Você também pode usar outros <em>frameworks </em>de teste, como o Mocha ou o Jasmine, mas eu vou usar o Jest porque ele funciona bem com o React e com a React Testing Library.</p><p>Para este tutorial, eu vou criar uma aplicação em React com o CRA usando o modelo padrão:</p><pre><code class="language-shell">npx create-react-app react-test-example</code></pre><h3 id="criando-uma-aplica-o-em-react-com-o-cra">Criando uma aplicação em React com o CRA</h3><p>Depois que a aplicação for criada, você deve ter um arquivo <code>App.test.js</code> já gerado dentro da pasta <code>src/</code>. O conteúdo do arquivo seria o seguinte:</p><pre><code class="language-javascript">import { render, screen } from '@testing-library/react';
import App from './App';

test('renders learn react link', () =&gt; {
  render(&lt;App /&gt;);
  const linkElement = screen.getByText(/learn react/i);
  expect(linkElement).toBeInTheDocument();
});</code></pre><h3 id="c-digo-de-teste-cra-padr-o">Código de teste CRA padrão</h3><p>O código de teste acima usou o método <code>render</code> da React Testing Library para renderizar virtualmente o componente <code>App</code> importado do arquivo <code>App.js</code> e anexá-lo ao nó <code>document.body</code>. Você pode acessar o HTML renderizado através do objeto <code>screen</code>.</p><p>Para ver o resultado da chamada de <code>render()</code>, você pode usar o método <code>screen.debug()</code>:</p><pre><code class="language-javascript">import { render, screen } from '@testing-library/react';
import App from './App';

test('renders learn react link', () =&gt; {
  render(&lt;App /&gt;);
  screen.debug();
});</code></pre><h3 id="depurando-os-elementos-renderizados-pela-react-testing-library">Depurando os elementos renderizados pela React Testing Library</h3><p>Abra seu terminal e execute o comando <code>npm run test</code>. Você verá toda a árvore <code>document.body</code> renderizada no seu console:</p><pre><code class="language-html">&lt;body&gt;
  &lt;div&gt;
    &lt;div class="App"&gt;
      &lt;header class="App-header"&gt;
        &lt;img alt="logo" class="App-logo" src="logo.svg" /&gt;
        &lt;p&gt;
          Edite &lt;code&gt;src/App.js&lt;/code&gt; e salve para recarregar.
        &lt;/p&gt;
        &lt;a
          class="App-link"
          href="https://reactjs.org"
          rel="noopener noreferrer"
          target="_blank"
        &gt;
          Aprenda React
        &lt;/a&gt;
      &lt;/header&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/body&gt;</code></pre><h3 id="corpo-do-documento-renderizado-pela-react-testing-library">Corpo do documento renderizado pela React Testing Library</h3><p>O objeto <code>screen</code> também possui os métodos de teste do DOM já vinculados a ele. É por isso que o código de teste acima poderia usar <code>screen.getByText()</code> para consultar o elemento de âncora <code>&lt;a&gt;</code> para ver o seu valor de <strong>textContent</strong>.</p><p>Finalmente, o código de teste confirmará se o elemento de link está disponível no objeto <code>document</code> ou não com o método <code>expect</code> do Jest:</p><pre><code class="language-javascript">expect(linkElement).toBeInTheDocument();</code></pre><h3 id="confirmando-se-o-elemento-de-link-est-no-documento">Confirmando se o elemento de link está no documento</h3><p>Quando o elemento de link não for encontrado, o Jest marcará o teste como <strong>falhado</strong> (em inglês, <em>fail</em>).</p><h2 id="m-todos-da-react-testing-library-para-encontrar-elementos">Métodos da React Testing Library para encontrar elementos</h2><p>A maioria dos seus casos de teste para o React deve usar métodos para encontrar elementos. A React Testing Library fornece vários métodos para encontrar um elemento por atributos específicos além do método <code>getByText()</code> acima:</p><ul><li><code>getByText()</code>: encontre o elemento pelo valor do atributo <code>textContent</code></li><li><code>getByRole()</code>: encontre o elemento pelo valor do atributo <code>role</code></li><li><code>getByLabelText()</code>: encontre o elemento pelo valor do atributo <code>label</code></li><li><code>getByPlaceholderText()</code>: encontre o elemento pelo valor do atributo <code>placeholder</code></li><li><code>getByAltText()</code>: encontre o elemento pelo valor do atributo <code>alt</code></li><li><code>getByDisplayValue()</code>: encontre o elemento pelo valor do atributo <code>value</code>, geralmente para elementos <code>&lt;input&gt;</code></li><li><code>getByTitle()</code>: encontre o elemento pelo valor do atributo <code>title</code></li></ul><p>Quando esses métodos não forem suficientes, você pode usar o método <code>getByTestId()</code>, que permite encontrar um elemento pelo atributo <code>data-testid</code>:</p><pre><code class="language-javascript">import { render, screen } from '@testing-library/react';

render(&lt;div data-testid="custom-element" /&gt;);
const element = screen.getByTestId('custom-element');</code></pre><h3 id="obter-elemento-pelo-valor-de-data-testid">Obter elemento pelo valor de <code>data-testid</code></h3><p>Como selecionar elementos usando atributos <code>data-testid</code> não se assemelha à maneira como um usuário real usaria sua aplicação, a documentação recomenda que você o use apenas como último recurso quando todos os outros métodos falharem em encontrar seu elemento. Geralmente, encontrar por <code>Text</code>, <code>Role</code> ou <code>Label</code> deverá cobrir a maioria dos casos.</p><h2 id="como-testar-eventos-gerados-pelo-usu-rio-com-a-react-testing-library">Como testar eventos gerados pelo usuário com a React Testing Library</h2><p>Além de descobrir se os elementos estão presentes no corpo do seu documento, a React Testing Library também ajudará você a testar eventos gerados pelo usuário, como clicar em um botão e digitar valores em uma caixa de texto.</p><p>A biblioteca <code>user-event</code> é uma biblioteca complementar para simular a interação do usuário com o navegador. Suponha que você tenha um componente de botão para alternar entre os temas Claro (<em>light</em>) e Escuro (<em>dark</em>), da seguinte maneira:</p><pre><code class="language-javascript">import React, { useState } from "react";

function App() {
  const [theme, setTheme] = useState("light");

  const toggleTheme = () =&gt; {
    const nextTheme = theme === "light" ? "dark" : "light";
    setTheme(nextTheme);
  };

  return &lt;button onClick={toggleTheme}&gt;
      Current theme: {theme}
    &lt;/button&gt;;
}

export default App;</code></pre><p>Em seguida, você cria um teste que encontra o botão e simula um evento de clique usando o método <code>userEvent.click()</code>. Depois que o botão for clicado, você pode afirmar que o teste é um sucesso inspecionando se o texto do elemento do botão contém "dark" ou não:</p><pre><code class="language-javascript">import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import App from "./App";

test("Test theme button toggle", () =&gt; {
  render(&lt;App /&gt;);
  const buttonEl = screen.getByText(/Current theme/i);

  userEvent.click(buttonEl);
  expect(buttonEl).toHaveTextContent(/dark/i);
});</code></pre><h3 id="testando-o-clique-do-usu-rio-em-um-bot-o-e-afirmar-o-conte-do">Testando o clique do usuário em um botão e afirmar o conteúdo</h3><p>É assim que você pode simular eventos do usuário com a React Testing Library. A biblioteca <code>user-event</code> também possui vários outros métodos, como <code>dblClick</code>, para clicar duas vezes em um elemento, e <code>type</code>, para digitar em uma caixa de texto. Você pode verificar a <a href="https://testing-library.com/docs/ecosystem-user-event">documentação da biblioteca</a> <a href="https://testing-library.com/docs/ecosystem-user-event"><code>user-event</code></a> (documentação em inglês) para mais informações.</p><h2 id="conclus-o">Conclusão</h2><blockquote>Quanto mais seus testes se assemelharem ao modo como seu software é usado, mais confiança eles poderão dar a você.<br>(Fonte: <a href="https://twitter.com/kentcdodds/status/977018512689455106">Kent C.Dodds</a>, autor da React Testing Library)</blockquote><p>Um usuário real não verá os detalhes de implementação como qual estado (em inglês, <em>state</em>) ou <em>props</em> estão atualmente em seus componentes do React. Eles só veem os elementos HTML renderizados no navegador. A React Testing Library o incentiva a testar o comportamento de sua aplicação em vez de detalhes de implementação.</p><p>Ao testar sua aplicação da maneira como um usuário a utilizaria, você pode ter certeza de que sua aplicação se comportará como esperado quando todos os casos de teste forem aprovados. Para mais informações, você pode visitar a <a href="https://testing-library.com/docs/react-testing-library/example-intro">documentação da React Testing Library</a> (documentação em inglês).</p><p>Se você gostou deste artigo e deseja melhorar em suas habilidades em JavaScript, recomendo que confira meu novo livro <em>Beginning Modern JavaScript</em> <a href="https://www.amazon.com.br/dp/B0CQXHMF8G">aqui</a> (e-book em inglês).</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/07/beginning-js-cover.png" class="kg-image" alt="beginning-js-cover" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/07/beginning-js-cover.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/07/beginning-js-cover.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/07/beginning-js-cover.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/07/beginning-js-cover.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="1667" loading="lazy"></figure><p>O livro foi projetado para ser fácil de entender e acessível a qualquer pessoa que queira aprender JavaScript. Ele fornece um guia passo a passo que ajudará você a entender como usar o JavaScript para criar uma aplicação dinâmica.</p><p>Posso prometer que <em>você realmente sentirá que entende o que está fazendo com JavaScript.</em></p><p>Até a próxima!</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Percorra objetos aninhados no React.js ]]>
                </title>
                <description>
                    <![CDATA[ Se você já trabalhou com APIs, sabe que a estrutura dos dados que elas retornam pode ficar complicada rapidamente. Imagine chamar uma API a partir do seu projeto em React e a resposta ter uma aparência semelhante a esta: Objeto1 {      Objeto2 {   ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/percorra-objetos-aninhados-no-react-js/</link>
                <guid isPermaLink="false">666ea64479dc5c03cfad3bc7</guid>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Daniel Rosa ]]>
                </dc:creator>
                <pubDate>Mon, 17 Jun 2024 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2024/06/5f9c9aa2740569d1a4ca26c5.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/iterate-through-nested-object-in-react-js/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Iterate Through Nested Object in React.js</a>
      </p><p>Se você já trabalhou com APIs, sabe que a estrutura dos dados que elas retornam pode ficar complicada rapidamente.</p><p>Imagine chamar uma API a partir do seu projeto em React e a resposta ter uma aparência semelhante a esta:</p><pre><code class="language-json">Objeto1 {
     Objeto2 {
           propriedadeQueEuQueroAcessar:
           outraPropriedadeQueEuQueroAcessar:
      }
}</code></pre><p>Você armazenou os dados no estado (em inglês, <em>state</em>) do seu componente como <code>this.state.myPosts</code>, podendo acessar os elementos de do objeto externo da seguinte maneira:</p><pre><code class="language-jsx">render() {
    console.log(this.state.myPosts);

    const data = this.state.myPosts;

    const display = Object.keys(data).map((d, key) =&gt; {
    return (
      &lt;div className="my-posts"&gt;
        &lt;li key={key}&gt;
          {data.current_route}
        &lt;/li&gt;
      &lt;/div&gt;
      );
    });

    return(
      &lt;div&gt;
        &lt;ul&gt;
          { display }
        &lt;/ul&gt;
      &lt;/div&gt;
    );
  }</code></pre><p>O problema, contudo, é o fato de que você não consegue acessar nada nos objetos internos.</p><p>Os valores dos objetos internos sempre mudarão. Assim, você não consegue simplesmente inserir os valores dessas chaves no código diretamente e percorrer essas chaves para obter os valores adequados.</p><h2 id="solu-es-poss-veis"><strong>Soluções possíveis</strong></h2><p>Pode ser difícil trabalhar diretamente com respostas complexas de APIs. Assim, vamos voltar um pouco e simplificar:</p><pre><code class="language-jsx">const visit = (obj, fn) =&gt; {
    const values = Object.values(obj)

    values.forEach(val =&gt; 
        val &amp;&amp; typeof val === "object" ? visit(val, fn) : fn(val))
}

// Teste rápido
const print = (val) =&gt; console.log(val)

const person = {
    name: {
        first: "João",
        last: "Ninguém"
    },
    age: 15,
    secret: {
        secret2: {
            secret3: {
                val: "Comi um cookie"
            }
        }
    }
}

visit(person, print)
/* Resultado
João
Ninguém
15
Comi um cookie
*/</code></pre><p>A biblioteca <code>lodash</code> tem métodos simples de se conseguir a mesma coisa, mas essa é uma maneira rápida e de se fazer o mesmo com JS puro.</p><p>Digamos, porém, que você quer simplificar ainda mais – algo assim:</p><pre><code class="language-jsx">render() {
    // Registraos dados
    console.log(this.state.myPosts);

    const data = this.state.myPosts;

    // Armazena o objeto aninhado que você quer acessar na variável posts
    const posts = data.content;

    // Registra com sucesso o objeto aninhado que eu quero acessar
    console.log(posts);

    // Erro, isto não me deixará passar a variável posts para Object.keys
    const display = Object.keys(posts).map(key =&gt;
      &lt;option value={key}&gt;{posts[key]}&lt;/option&gt;
    )


    return(
      &lt;div&gt;
        {display}
      &lt;/div&gt;
    );
 }</code></pre><p>Você, porém, chega no erro <code>TypeError: can't convert undefined to object error</code> sempre que tenta passar <code>posts</code> para <code>Object.keys</code>.</p><p>Lembre-se de que esse erro nada tem a ver com o React. Não é uma operação legl passar um objeto como filho de um componente.</p><p><code>Object.keys()</code> retorna apenas as chaves de objeto que são passadas como parâmetro. Você precisaria chamá-lo diversas vezes para percorrer todas as chaves aninhadas.</p><p>Se desejar exibir todo o objeto aninhado, uma opção é usar uma função que converta cada objeto em um componente do React e que o passe em um <em>array</em>:</p><pre><code class="language-jsx">let data= []

visit(obj, (val) =&gt; {
    data.push(&lt;p&gt;{val}&lt;/p&gt;)  // envolve em um &lt;p&gt; qualquer tipo que não seja um objeto
})
...
return &lt;UmComponenteQualquer&gt; {data} &lt;/UmComponenteQualquer&gt;</code></pre><h2 id="pacotes-teis"><strong>Pacotes úteis</strong></h2><p>Outra opção é usar um pacote como o <a href="https://www.npmjs.com/package/json-query">json-query</a> para ajudar a percorrer os dados em JSON aninhados.</p><p>Aqui temos uma versão modificada da função <code>render</code> acima usando o <code>json-query</code>:</p><pre><code class="language-jsx"> render() {
   const utopian = Object.keys(this.state.utopianCash);
   console.log(this.state.utopianCash);

   var author = jsonQuery('[*][author]', { data: this.state.utopianCash }).value
   var title = jsonQuery('[*][title]', { data: this.state.utopianCash }).value
   var payout = jsonQuery('[*][total_payout_value]', { data: this.state.utopianCash }).value
   var postLink = jsonQuery('[*][url]', { data: this.state.utopianCash }).value
   var pendingPayout = jsonQuery('[*][pending_payout_value]', { data: this.state.utopianCash }).value
   var netVotes = jsonQuery('[*][net_votes]', { data: this.state.utopianCash }).value


   let display = utopian.map((post, i) =&gt; {
     return (
       &lt;div className="utopian-items"&gt;
        &lt;p&gt;
          &lt;strong&gt;Author: &lt;/strong&gt;
          {author[i]}
        &lt;/p&gt;
        &lt;p&gt;
          &lt;strong&gt;Title: &lt;/strong&gt;
            &lt;a href={`https://www.steemit.com` + postLink[i]}&gt;{title[i]}&lt;/a&gt;
        &lt;/p&gt;
        &lt;p&gt;
          &lt;strong&gt;Pending Payout: &lt;/strong&gt;
            {pendingPayout[i]}
        &lt;/p&gt;
        &lt;p&gt;
          &lt;strong&gt;Votes: &lt;/strong&gt;
          {netVotes[i]}
        &lt;/p&gt;
       &lt;/div&gt;
     );
   });

    return (
      &lt;div className="utopian-container"&gt;
        {display}
        &lt;User /&gt;
      &lt;/div&gt;
    );
  }
}</code></pre> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como começar a testar suas aplicações em React usando a React Testing Library e o Jest ]]>
                </title>
                <description>
                    <![CDATA[  Testes são frequentemente vistos como um processo tedioso. É código extra que você tem que escrever e, em alguns casos, para ser honesto, não é necessário. Todo desenvolvedor, no entanto, deve saber pelo menos o básico de testes. Isso aumenta a confiança nos produtos que eles constroem e, na ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/comece-a-testar-suas-aplicacoes-em-react-usando-a-react-testing-library-e-o-jest/</link>
                <guid isPermaLink="false">652ad812b73e2e03f70ce8f3</guid>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ana Laura Reis ]]>
                </dc:creator>
                <pubDate>Tue, 04 Jun 2024 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/cover-3.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/8-simple-steps-to-start-testing-react-apps-using-react-testing-library-and-jest/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Start Testing Your React Apps Using the React Testing Library and Jest</a>
      </p><p></p><p>Testes são frequentemente vistos como um processo tedioso. É código extra que você tem que escrever e, em alguns casos, para ser honesto, não é necessário. Todo desenvolvedor, no entanto, deve saber pelo menos o básico de testes. Isso aumenta a confiança nos produtos que eles constroem e, na maioria das empresas, é um requisito.</p><p>No mundo do React, há uma incrível biblioteca chamada <code>react-testing-library</code>, que auxilia no teste mais eficiente de suas aplicações em React. Você a utiliza com o Jest.</p><p>Neste artigo, veremos 8 etapas simples para começar a testar suas aplicações em React como um especialista.</p><ul><li><a href="https://www.freecodecamp.org/portuguese/news/comece-a-testar-suas-aplicacoes-em-react-usando-a-react-testing-library-e-o-jest/#pr-requisitos">Pré-requisitos</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/comece-a-testar-suas-aplicacoes-em-react-usando-a-react-testing-library-e-o-jest/#b-sico">Básico</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/comece-a-testar-suas-aplicacoes-em-react-usando-a-react-testing-library-e-o-jest/#o-que-a-react-testing-library">O que é a React Testing Library?</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/comece-a-testar-suas-aplicacoes-em-react-usando-a-react-testing-library-e-o-jest/#\31%20-como-criar-um-snapshot-de-teste">1. Como criar um <em>snapshot</em> do teste?</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/comece-a-testar-suas-aplicacoes-em-react-usando-a-react-testing-library-e-o-jest/#\32%20-testando-elementos-do-dom">2. Testando elementos do DOM </a></li><li><a href="https://www.freecodecamp.org/portuguese/news/comece-a-testar-suas-aplicacoes-em-react-usando-a-react-testing-library-e-o-jest/#\33%20-testando-eventos">3. Testando eventos</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/comece-a-testar-suas-aplicacoes-em-react-usando-a-react-testing-library-e-o-jest/#\34%20-testando-a-es-ass-ncronas">4. Testando ações assíncronas</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/comece-a-testar-suas-aplicacoes-em-react-usando-a-react-testing-library-e-o-jest/#\35%20-testando-o-react-redux">5. Testando o React Redux</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/comece-a-testar-suas-aplicacoes-em-react-usando-a-react-testing-library-e-o-jest/#\36%20-testando-o-react-context">6. Testando o React Context</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/comece-a-testar-suas-aplicacoes-em-react-usando-a-react-testing-library-e-o-jest/#\37%20-testando-o-react-router">7. Testando o React Router</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/comece-a-testar-suas-aplicacoes-em-react-usando-a-react-testing-library-e-o-jest/#\38%20-testando-requisi-es-http">8. Testando requisições HTTP</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/comece-a-testar-suas-aplicacoes-em-react-usando-a-react-testing-library-e-o-jest/#conclus-o">Conclusão</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/comece-a-testar-suas-aplicacoes-em-react-usando-a-react-testing-library-e-o-jest/#pr-ximos-passos-documenta-es-em-ingl-s-">Próximos passos</a></li></ul><h2 id="pr-requisitos"><strong>Pré-requisitos</strong></h2><p>Neste tutorial, pressupõe-se que você tenha, pelo menos, um entendimento básico do React. Vou focar apenas na parte de testes.</p><p>Para acompanhá-lo, você precisa clonar o projeto, executando no seu terminal:</p><pre><code class="language-shell">  git clone https://github.com/ibrahima92/prep-react-testing-library-guide
</code></pre><p>Depois, execute:</p><pre><code class="language-shell">  yarn
</code></pre><p>Ou, se estiver usando o npm:</p><pre><code class="language-shell">npm install
</code></pre><p>É isso! Agora, vamos mergulhar em alguns princípios básicos.</p><h2 id="b-sico"><strong>Básico</strong></h2><p>Alguns pontos-chave serão amplamente utilizados neste artigo. Compreender o papel deles pode auxiliar na compreensão</p><p><code>it ou test</code>: descreve o próprio teste. Recebe como parâmetros o nome do teste e uma função que contém os testes.</p><p><code>expect</code>: a condição que o teste precisa satisfazer. Ela vai comparar o parâmetro recebido com um '<em>matcher</em>'.</p><p><code>matcher</code>: a função aplicada à condição esperada.</p><p><code>render</code>: o método usado para renderizar um determinado componente</p><pre><code class="language-jsx">import React from 'react'
import {render} from '@testing-library/react'
import App from './App'
 
 it('should take a snapshot', () =&gt; {
    const { asFragment } = render(&lt;App /&gt;)
    
    expect(asFragment(&lt;App /&gt;)).toMatchSnapshot()
   })
});
</code></pre><p>Como você pode ver, descrevemos o teste com isso. Em seguida, usamos o <em>render</em> para exibir o componente e esperamos que <code>asFragment(&lt;App /&gt;)</code> corresponda a <code>toMatchSnapshot()</code> (o verificador fornecido pelo <a href="https://github.com/testing-library/jest-dom">jest-dom</a>).</p><p>A propósito, o método <em>render</em> retorna vários métodos que podemos usar para testar nossos recursos. Também usamos a desestruturação para obter o método.</p><p>Dito isso, vamos avançar e aprender mais sobre a React Testing Library na próxima seção.</p><h2 id="o-que-a-react-testing-library"><strong>O que é a React Testing Library?</strong></h2><p>A React Testing Library é um pacote muito leve e excelente criado por <a href="https://twitter.com/kentcdodds">Kent C. Dodds</a>. É uma substituição para o <a href="https://enzymejs.github.io/enzyme/">Enzyme</a> e fornece funções utilitárias leves em cima do `react-dom` &nbsp;e `react-dom/test-utils`.</p><p>O React Testing Library é uma biblioteca de teste de DOM, o que significa que, em vez de lidar com instâncias de componentes do React renderizados, ele lida com elementos do DOM e com o modo como eles se comportam diante de usuários reais.</p><p>É uma ótima biblioteca, relativamente fácil de começar a usar, e promove boas práticas de teste. Observação: você também pode utilizá-la sem o Jest.</p><p>"Quanto mais seus testes se assemelharem à maneira como seu software é utilizado, maior confiança eles podem lhe proporcionar".</p><p>Agora, vamos começar a utilizá-los na próxima seção. Aliás, você não precisa instalar nenhum pacote, já que o create-react-app vem com a biblioteca e suas dependências.</p><h2 id="1-como-criar-um-snapshot-de-teste"><strong>1. Como criar um <em>snapshot</em> de teste</strong></h2><p>Um <em>snapshot </em>(em português, algo como uma fotografia ou instantâneo), como o nome sugere, nos permite salvar uma imagem do estado atual de um componente específico. Isso é especialmente útil quando você faz atualizações ou realiza alguma refatoração e deseja obter ou comparar as mudanças.</p><p>Agora, vamos tirar um <em>snapshot</em> do arquivo <code>App.js</code> .</p><ul><li><code>App.test.js</code></li></ul><pre><code class="language-jsx">import React from 'react'
import {render, cleanup} from '@testing-library/react'
import App from './App'

 afterEach(cleanup)
 
 it('should take a snapshot', () =&gt; {
    const { asFragment } = render(&lt;App /&gt;)
    
    expect(asFragment(&lt;App /&gt;)).toMatchSnapshot()
   })
});
</code></pre><p>Para tirar um <em>snapshot</em>, primeiro precisamos importar os métodos <code>render</code> e <code>cleanup</code>. Esses dois métodos serão amplamente utilizados ao longo deste artigo</p><p><code>render</code>, como você pode imaginar, é usado para renderizar um componente do React. A função <code>cleanup</code> é passada como um parâmetro para o <code>afterEach</code> para limpar tudo após cada teste, a fim de evitar vazamentos de memória.</p><p>Agora, podemos renderizar o componente App com o método <code>render</code> e obter <code>asFragment</code> como o valor retornado. Por fim, nos certificamos de que o fragmento do componente corresponda ao <em>snapshot</em>.</p><p>Agora, para executar o teste, abra o termina, navegue até a raiz do projeto e execute o seguinte comando:</p><pre><code class="language-shell">  yarn test
</code></pre><p>Ou, se estiver usando npm:</p><pre><code class="language-shell">  npm test
</code></pre><p>Como resultado, ele criará uma outra pasta <code>__snapshots__</code> e um arquivo <code>App.test.js.snap</code> na pasta <code>src</code>, que se parecerá com isto:</p><ul><li><code>App.test.js.snap</code></li></ul><pre><code class="language-jsx">// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Take a snapshot should take a snapshot 1`] = `
&lt;DocumentFragment&gt;
  &lt;div class="App"&gt;
    &lt;h1&gt;Testing&lt;/h1&gt;
  &lt;/div&gt;
&lt;/DocumentFragment&gt;
`;
</code></pre><p>Se você fizer outra alteração em <code>App.js</code>, o teste falhará, pois o <em>snapshot</em> não corresponderá mais à condição. Para fazê-lo passar, basta pressionar 'u' para atualizá-lo. Você terá o snapshot atualizado no arquivo <code>App.test.js.snap</code>.</p><p>Agora, vamos prosseguir e começar a testar nossos elementos.</p><h2 id="2-testando-elementos-do-dom"><strong>2. Testando elementos do DOM </strong></h2><p>Para testar nossos elementos do DOM, primeiro devemos examinar o arquivo <code>TestElements.js</code></p><ul><li><code>TestElements.js</code></li></ul><pre><code class="language-jsx">import React from 'react'

const TestElements = () =&gt; {
 const [counter, setCounter] = React.useState(0)
  
 return (
  &lt;&gt;
    &lt;h1 data-testid="counter"&gt;{ counter }&lt;/h1&gt;
    &lt;button data-testid="button-up" onClick={() =&gt; setCounter(counter + 1)}&gt; Up&lt;/button&gt;
    &lt;button disabled data-testid="button-down" onClick={() =&gt; setCounter(counter - 1)}&gt;Down&lt;/button&gt;
 &lt;/&gt;
    )
  }
  
export default TestElements
</code></pre><p>Aqui, a única coisa que você precisa manter é o <code>data-testid</code>. Ele será usado para selecionar esses elementos no arquivo de teste. Agora, vamos escrever nosso teste unitário.</p><p>Teste se o contador está igual a 0:</p><p><code>TestElements.test.js</code></p><pre><code class="language-jsx">import React from 'react';
import { render, cleanup } from '@testing-library/react';
import TestElements from './TestElements'

afterEach(cleanup);

  it('should equal to 0', () =&gt; {
    const { getByTestId } = render(&lt;TestElements /&gt;); 
    expect(getByTestId('counter')).toHaveTextContent(0)
   });
</code></pre><p>Como você pode notar, a sintaxe é bastante similar ao teste anterior. A única diferença é que usamos getByTestId para selecionar os elementos necessários (lembre-se de data-testid) e checamos se isso passava no teste. Em outras palavras, verificamos se o conteúdo do texto <code>&lt;h1 data-testid="counter"&gt;{ counter }&lt;/h1&gt;</code> é igual a zero.</p><p>Teste se os botões estão habilitados ou desabilitados:</p><p><code>TestElements.test.js</code> (adicione o seguinte bloco de código no arquivo)</p><pre><code class="language-jsx">   it('should be enabled', () =&gt; {
    const { getByTestId } = render(&lt;TestElements /&gt;);
    expect(getByTestId('button-up')).not.toHaveAttribute('disabled')
  });

  it('should be disabled', () =&gt; {
    const { getByTestId } = render(&lt;TestElements /&gt;); 
    expect(getByTestId('button-down')).toBeDisabled()
  });
</code></pre><p>Aqui, como de costume, usamos getByTestId para selecionar os elementos e verificar no primeiro teste se o botão possui o atributo 'disabled'. No segundo teste, verificamos se o botão está desabilitado ou não.</p><p>Se você salvar o arquivo ou rodar novamente no seu terminal o comando 'yarn test', os testes passarão.</p><p>Parabéns! Seu primeiro teste passou!</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/source.gif" class="kg-image" alt="source" width="498" height="243" loading="lazy"></figure><p>Agora, vamos aprender como testar um evento na próxima seção.</p><h2 id="3-testando-eventos"><strong>3. Testando eventos</strong></h2><p>Antes de escrever nossos testes unitários, vamos primeiro verificar como é o arquivo <code>TestEvents.js</code></p><ul><li><code>TestEvents.js</code></li></ul><pre><code class="language-jsx">import React from 'react'

const TestEvents = () =&gt; {
  const [counter, setCounter] = React.useState(0)
  
return (
  &lt;&gt;
    &lt;h1 data-testid="counter"&gt;{ counter }&lt;/h1&gt;
    &lt;button data-testid="button-up" onClick={() =&gt; setCounter(counter + 1)}&gt; Up&lt;/button&gt;
    &lt;button data-testid="button-down" onClick={() =&gt; setCounter(counter - 1)}&gt;Down&lt;/button&gt;
 &lt;/&gt;
    )
  }
  
  export default TestEvents
</code></pre><p>Agora, vamos escrever os testes.</p><p>Teste se o contador incrementa e decrementa corretamente quando clicamos nos botões</p><p><code>TestEvents.test.js</code></p><pre><code class="language-jsx">import React from 'react';
import { render, cleanup, fireEvent } from '@testing-library/react';
import TestEvents from './TestEvents'

  afterEach(cleanup);
  
  it('increments counter', () =&gt; {
    const { getByTestId } = render(&lt;TestEvents /&gt;); 
    
    fireEvent.click(getByTestId('button-up'))

    expect(getByTestId('counter')).toHaveTextContent('1')
  });

  it('decrements counter', () =&gt; {
    const { getByTestId } = render(&lt;TestEvents /&gt;); 
    
    fireEvent.click(getByTestId('button-down'))

    expect(getByTestId('counter')).toHaveTextContent('-1')
  });

</code></pre><p>Como você pode ver, esses dois testes são muito semelhantes, exceto pelo conteúdo de texto esperado. O primeiro teste dispara um evento de clique com <code>fireEvent.click()</code> para verificar se o contador incrementa para 1 quando o botão é clicado.</p><p>O segundo teste verifica se o contador decrementa para -1 quando o botão é clicado.</p><p><code>fireEvent</code> tem vários métodos que você pode usar para testar eventos. Fique à vontade para mergulhar na documentação e aprender mais.</p><p>Agora que sabemos como testar eventos, vamos avançar e aprender na próxima seção como lidar com ações assíncronas.</p><h2 id="4-testando-a-es-ass-ncronas"><strong>4. </strong>Testando ações assíncronas</h2><p>Uma ação assíncrona é algo que pode levar tempo para ser concluído. Pode ser uma solicitação HTTP, um temporizador e assim por diante. </p><p>Agora, vamos verificar o arquivo <code>TestAsync.js</code>.</p><ul><li><code>TestAsync.js</code></li></ul><pre><code class="language-jsx">import React from 'react'

const TestAsync = () =&gt; {
  const [counter, setCounter] = React.useState(0)

  const delayCount = () =&gt; (
    setTimeout(() =&gt; {
      setCounter(counter + 1)
    }, 500)
  )
  
return (
  &lt;&gt;
    &lt;h1 data-testid="counter"&gt;{ counter }&lt;/h1&gt;
    &lt;button data-testid="button-up" onClick={delayCount}&gt; Up&lt;/button&gt;
    &lt;button data-testid="button-down" onClick={() =&gt; setCounter(counter - 1)}&gt;Down&lt;/button&gt;
 &lt;/&gt;
    )
  }
  
  export default TestAsync
</code></pre><p>Aqui, usamos <code>setTimeout()</code> para atrasar o evento de incremento em 0,5 segundo. </p><p>Teste se o contador é incrementado após 0,5 segundo: <code>TestAsync.test.js</code></p><pre><code class="language-jsx">import React from 'react';
import { render, cleanup, fireEvent, waitForElement } from '@testing-library/react';
import TestAsync from './TestAsync'

afterEach(cleanup);
  
  it('increments counter after 0.5s', async () =&gt; {
    const { getByTestId, getByText } = render(&lt;TestAsync /&gt;); 

    fireEvent.click(getByTestId('button-up'))

    const counter = await waitForElement(() =&gt; getByText('1')) 

    expect(counter).toHaveTextContent('1')
  });
</code></pre><p><br>Para testar o evento de incremento, primeiro precisamos usar async/await para lidar com a ação, porque, como mencionei anteriormente, ela leva tempo para ser concluída. </p><p>Em seguida, usamos um novo método auxiliar <code>getByText()</code>. Ele é semelhante ao <code>getByTestId()</code>, exceto pelo fato de que <code>getByText()</code> seleciona o conteúdo do texto em vez do <code>id</code> ou <code>data-testid</code>. </p><p>Agora, após clicar no botão, esperamos que o contador seja incrementado com <code>waitForElement(() =&gt; getByText('1'))</code>. Uma vez que o contador foi incrementado para 1, podemos passar para a condição e verificar se o contador é efetivamente igual a 1. Dito isso, vamos agora passar para casos de teste mais complexos.</p><p> Você está pronto?</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/source--1-.gif" class="kg-image" alt="source--1-" width="1056" height="594" loading="lazy"></figure><h2 id="5-testando-o-react-redux"><strong>5. </strong>Testando o React Redux </h2><p>Se você é novo no React Redux, <a href="https://www.ibrahima-ndaw.com/blog/7-steps-to-understand-react-redux/">este artigo</a> (texto em inglês) pode ajudar você. Caso contrário, vamos verificar como o TestRedux.js se parece.</p><ul><li><code>TestRedux.js</code></li></ul><pre><code class="language-jsx">import React from 'react'
import { connect } from 'react-redux'

const TestRedux = ({counter, dispatch}) =&gt; {

 const increment = () =&gt; dispatch({ type: 'INCREMENT' })
 const decrement = () =&gt; dispatch({ type: 'DECREMENT' })
  
 return (
  &lt;&gt;
    &lt;h1 data-testid="counter"&gt;{ counter }&lt;/h1&gt;
    &lt;button data-testid="button-up" onClick={increment}&gt;Up&lt;/button&gt;
    &lt;button data-testid="button-down" onClick={decrement}&gt;Down&lt;/button&gt;
 &lt;/&gt;
    )
  }
  
export default connect(state =&gt; ({ counter: state.count }))(TestRedux)
</code></pre><p>Agora, para o Redux:</p><ul><li><code>store/reducer.js</code></li></ul><pre><code class="language-jsx">export const initialState = {
    count: 0,
  }
  
  export function reducer(state = initialState, action) {
    switch (action.type) {
      case 'INCREMENT':
        return {
          count: state.count + 1,
        }
      case 'DECREMENT':
        return {
          count: state.count - 1,
        }
      default:
        return state
    }
  }
</code></pre><p>Como você pode ver, não há nada extravagante – é apenas um componente Counter básico manipulado pelo React Redux. </p><p>Agora, vamos escrever os testes unitários. </p><p>Teste se o estado inicial é igual a 0:</p><p><code>TestRedux.test.js</code></p><pre><code class="language-jsx">import React from 'react'
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import { render, cleanup, fireEvent } from '@testing-library/react';
import { initialState, reducer } from '../store/reducer'
import TestRedux from './TestRedux'

const renderWithRedux = (
  component,
  { initialState, store = createStore(reducer, initialState) } = {}
) =&gt; {
  return {
    ...render(&lt;Provider store={store}&gt;{component}&lt;/Provider&gt;),
    store,
  }
}

 afterEach(cleanup);

it('checks initial state is equal to 0', () =&gt; {
    const { getByTestId } = renderWithRedux(&lt;TestRedux /&gt;)
    expect(getByTestId('counter')).toHaveTextContent('0')
  })
</code></pre><p>Existem algumas coisas que precisamos importar para testar o React Redux. Aqui, criamos nossa própria função auxiliar <code>renderWithRedux()</code> para renderizar o componente, já que ele será usado várias vezes.</p><p><code>renderWithRedux()</code> recebe como parâmetros o componente a ser renderizado, o estado inicial e a loja.</p><p>Se não houver loja, ele criará uma. Se não receber um estado inicial ou uma loja, ele retornará um objeto vazio. </p><p>Em seguida, usamos <code>render()</code> para renderizar o componente e passamos a loja para o <code>Provider</code>. Dito isso, agora, podemos passar o componente <code>TestRedux</code> para <code>renderWithRedux()</code> para testar se o contador é igual a 0. </p><p>Teste se o contador incrementa e decrementa corretamente: <code>TestRedux.test.js</code> (adicione o seguinte bloco de código ao arquivo)</p><pre><code class="language-jsx">it('increments the counter through redux', () =&gt; {
  const { getByTestId } = renderWithRedux(&lt;TestRedux /&gt;, 
    {initialState: {count: 5}
})
  fireEvent.click(getByTestId('button-up'))
  expect(getByTestId('counter')).toHaveTextContent('6')
})

it('decrements the counter through redux', () =&gt; {
  const { getByTestId} = renderWithRedux(&lt;TestRedux /&gt;, {
    initialState: { count: 100 },
  })
  fireEvent.click(getByTestId('button-down'))
  expect(getByTestId('counter')).toHaveTextContent('99')
})
</code></pre><p><br>Para testar os eventos de incremento e decremento, passamos um estado inicial como segundo argumento para <code>renderWithRedux()</code>. </p><p>Agora, podemos clicar nos botões e testar se o resultado esperado corresponde à condição ou não.</p><p>Vamos passar para a próxima seção e introduzir o React Context. React Router e Axios virão em seguida – você ainda está comigo?</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/source--2-.gif" class="kg-image" alt="source--2-" width="480" height="264" loading="lazy"></figure><h2 id="6-testando-o-react-context"><strong>6. </strong>Testando o React Context</h2><p>Se você é novo no React Context, confira <a href="https://www.ibrahima-ndaw.com/blog/redux-vs-react-context-which-one-should-you-choose/">este artigo</a> primeiro (texto em inglês). Caso contrário, vamos verificar o arquivo <code>TextContext.js</code>.</p><ul><li><code>TextContext.js</code></li></ul><pre><code class="language-jsx">import React from "react"

export const CounterContext = React.createContext()

const CounterProvider = () =&gt; {
  const [counter, setCounter] = React.useState(0)
  const increment = () =&gt; setCounter(counter + 1)
  const decrement = () =&gt; setCounter(counter - 1)

  return (
    &lt;CounterContext.Provider value={{ counter, increment, decrement }}&gt;
      &lt;Counter /&gt;
    &lt;/CounterContext.Provider&gt;
  )
}

export const Counter = () =&gt; {  
    const { counter, increment, decrement } = React.useContext(CounterContext)   
    return (
     &lt;&gt;
       &lt;h1 data-testid="counter"&gt;{ counter }&lt;/h1&gt;
       &lt;button data-testid="button-up" onClick={increment}&gt; Up&lt;/button&gt;
       &lt;button data-testid="button-down" onClick={decrement}&gt;Down&lt;/button&gt;
    &lt;/&gt;
       )
}

export default CounterProvider
</code></pre><p><br>Agora, o estado do contador é gerenciado por meio do React Context. Vamos escrever o teste unitário para verificar se ele se comporta conforme esperado.</p><p>Teste se o estado inicial é igual a 0:</p><p><code>TextContext.test.js</code></p><pre><code class="language-jsx">import React from 'react'
import { render, cleanup,  fireEvent } from '@testing-library/react'
import CounterProvider, { CounterContext, Counter } from './TestContext'

const renderWithContext = (
  component) =&gt; {
  return {
    ...render(
        &lt;CounterProvider value={CounterContext}&gt;
            {component}
        &lt;/CounterProvider&gt;)
  }
}

afterEach(cleanup);

it('checks if initial state is equal to 0', () =&gt; {
    const { getByTestId } = renderWithContext(&lt;Counter /&gt;)
    expect(getByTestId('counter')).toHaveTextContent('0')
})
</code></pre><p><br>Assim como na seção anterior com o React Redux, aqui usamos a mesma abordagem, criando uma função auxiliar <code>renderWithContext()</code> para renderizar o componente. </p><p>Dessa vez, porém, ela recebe apenas o componente como parâmetro. Para criar um outro contexto, passamos <code>CounterContext</code> para o <code>Provider</code>. Agora, podemos testar se o contador é inicialmente igual a 0 ou não. </p><p>Teste se o contador incrementa e decrementa corretamente: <code>TextContext.test.js</code> (adicione o seguinte bloco de código ao arquivo)</p><pre><code class="language-jsx">  it('increments the counter', () =&gt; {
    const { getByTestId } = renderWithContext(&lt;Counter /&gt;)

    fireEvent.click(getByTestId('button-up'))
    expect(getByTestId('counter')).toHaveTextContent('1')
  })

  it('decrements the counter', () =&gt; {
    const { getByTestId} = renderWithContext(&lt;Counter /&gt;)

    fireEvent.click(getByTestId('button-down'))
    expect(getByTestId('counter')).toHaveTextContent('-1')
  })
</code></pre><p>Como você pode ver, aqui disparamos um evento de clique para testar se o contador incrementa corretamente para 1 e decrementa para -1. </p><p>Dito isso, podemos passar para a próxima seção e introduzir o React Router.</p><h2 id="7-testando-o-react-router"><strong>7. </strong>Testando o React Router</h2><p>Se você quiser se aprofundar no React Router, <a href="https://www.ibrahima-ndaw.com/blog/the-complete-guide-to-react-router/">este artigo</a> pode ajudar você (texto em inglês). Caso contrário, vamos verificar o arquivo <code>TestRouter.js</code>.</p><ul><li><code>TestRouter.js</code></li></ul><pre><code class="language-jsx">import React from 'react'
import { Link, Route, Switch,  useParams } from 'react-router-dom'

const About = () =&gt; &lt;h1&gt;About page&lt;/h1&gt;

const Home = () =&gt; &lt;h1&gt;Home page&lt;/h1&gt;

const Contact = () =&gt; {
  const { name } = useParams()
  return &lt;h1 data-testid="contact-name"&gt;{name}&lt;/h1&gt;
}

const TestRouter = () =&gt; {
    const name = 'John Doe'
    return (
    &lt;&gt;
    &lt;nav data-testid="navbar"&gt;
      &lt;Link data-testid="home-link" to="/"&gt;Home&lt;/Link&gt;
      &lt;Link data-testid="about-link" to="/about"&gt;About&lt;/Link&gt;
      &lt;Link data-testid="contact-link" to={`/contact/${name}`}&gt;Contact&lt;/Link&gt;
    &lt;/nav&gt;
    
      &lt;Switch&gt;
        &lt;Route exact path="/" component={Home} /&gt;
        &lt;Route path="/about" component={About} /&gt;
        &lt;Route path="/about:name" component={Contact} /&gt;
      &lt;/Switch&gt;
    &lt;/&gt;
  )
}

export default TestRouter
</code></pre><p>Aqui, temos alguns componentes para renderizar ao navegar pela página inicial. </p><p>Agora, vamos escrever os testes:</p><ul><li><code>TestRouter.test.js</code></li></ul><pre><code class="language-jsx">import React from 'react'
import { Router } from 'react-router-dom'
import { render, fireEvent } from '@testing-library/react'
import { createMemoryHistory } from 'history'
import TestRouter from './TestRouter'


const renderWithRouter = (component) =&gt; {
    const history = createMemoryHistory()
    return { 
    ...render (
    &lt;Router history={history}&gt;
        {component}
    &lt;/Router&gt;
    )
  }
}

it('should render the home page', () =&gt; {

  const { container, getByTestId } = renderWithRouter(&lt;TestRouter /&gt;) 
  const navbar = getByTestId('navbar')
  const link = getByTestId('home-link')

  expect(container.innerHTML).toMatch('Home page')
  expect(navbar).toContainElement(link)
})
</code></pre><p><br>Para testar o React Router, primeiro, precisamos ter um histórico de navegação para começar. </p><p>Portanto, usamos <code>createMemoryHistory()</code> para, como o nome sugere, criar um histórico de navegação. Em seguida, usamos nossa função auxiliar <code>renderWithRouter()</code> para renderizar o componente e passamos o histórico para o componente Router. Com isso, podemos agora testar se a página carregada no início é a página inicial ou não e se a barra de navegação é carregada com os links esperados. </p><p>Teste se ele navega para outras páginas com os parâmetros quando clicamos nos links: <code>TestRouter.test.js</code> (adicione o seguinte bloco de código ao arquivo)</p><pre><code class="language-jsx">it('should navigate to the about page', ()=&gt; {
  const { container, getByTestId } = renderWithRouter(&lt;TestRouter /&gt;) 

  fireEvent.click(getByTestId('about-link'))

  expect(container.innerHTML).toMatch('About page')
})

it('should navigate to the contact page with the params', ()=&gt; {
  const { container, getByTestId } = renderWithRouter(&lt;TestRouter /&gt;) 
   
  fireEvent.click(getByTestId('contact-link'))
   
  expect(container.innerHTML).toMatch('John Doe')
})
</code></pre><p><br>Agora, para verificar se a navegação funciona, precisamos disparar um evento de clique nos links de navegação. Para o primeiro teste, verificamos se o conteúdo é igual ao texto na página Sobre (em inglês, <em>about</em>) e, para o segundo, testamos os parâmetros de roteamento e verificamos se foram passados corretamente. </p><p>Podemos passar para a seção final e aprender como testar uma solicitação com o Axios. </p><p><em>Estamos quase lá!</em></p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/source--3-.gif" class="kg-image" alt="source--3-" width="600" height="600" loading="lazy"></figure><h2 id="8-testando-requisi-es-http"><strong>8. </strong>Testando requisições HTTP</h2><p>Como de costume, vamos primeiro ver como é o arquivo <code>TextAxios.js</code>.</p><ul><li><code>TextAxios.js</code></li></ul><pre><code class="language-jsx">import React from 'react'
import axios from 'axios'

const TestAxios = ({ url }) =&gt; {
  const [data, setData] = React.useState()

  const fetchData = async () =&gt; {
    const response = await axios.get(url)
    setData(response.data.greeting)    
 }     
 
 return (
  &lt;&gt;
    &lt;button onClick={fetchData} data-testid="fetch-data"&gt;Load Data&lt;/button&gt;
    { 
    data ?
    &lt;div data-testid="show-data"&gt;{data}&lt;/div&gt;:
    &lt;h1 data-testid="loading"&gt;Loading...&lt;/h1&gt;
    }
  &lt;/&gt;
     )
}

export default TestAxios
</code></pre><p>Como você pode ver aqui, temos um componente simples que tem um botão para fazer uma solicitação. </p><p>Se os dados não estiverem disponíveis, ele exibirá uma mensagem de carregamento. </p><p>Agora, vamos escrever os testes. Teste se os dados são buscados e exibidos corretamente:</p><p><code>TextAxios.test.js</code></p><pre><code class="language-jsx">import React from 'react'
import { render, waitForElement, fireEvent } from '@testing-library/react'
import axiosMock from 'axios'
import TestAxios from './TestAxios'

jest.mock('axios')

it('should display a loading text', () =&gt; {

 const { getByTestId } = render(&lt;TestAxios /&gt;)

  expect(getByTestId('loading')).toHaveTextContent('Loading...')
})

it('should load and display the data', async () =&gt; {
  const url = '/greeting'
  const { getByTestId } = render(&lt;TestAxios url={url} /&gt;)

  axiosMock.get.mockResolvedValueOnce({
    data: { greeting: 'hello there' },
  })

  fireEvent.click(getByTestId('fetch-data'))

  const greetingData = await waitForElement(() =&gt; getByTestId('show-data'))

  expect(axiosMock.get).toHaveBeenCalledTimes(1)
  expect(axiosMock.get).toHaveBeenCalledWith(url)
  expect(greetingData).toHaveTextContent('hello there')
})
</code></pre><p>Esse caso de teste é um pouco diferente, pois lidamos com uma requisição HTTP e, para fazer isso, temos que simular uma solicitação do Axios com a ajuda de <code>jest.mock('axios')</code>. </p><p>Agora, podemos usar <code>axiosMock</code> e aplicar um método <code>get()</code> a ele. Finalmente, usaremos a função <code>mockResolvedValueOnce()</code> do Jest para passar os dados simulados como parâmetro. </p><p>Com isso, para o segundo teste, podemos clicar no botão para buscar os dados e usar async/await para resolvê-los. </p><p>Temos que testar 3 coisas: </p><ol><li>Se a requisição HTTP foi feita corretamente; </li><li>Se a requisição HTTP foi feita com o URL correto;</li><li>Se os dados buscados correspondem à expectativa. </li></ol><p>Para o primeiro teste, apenas verificamos se a mensagem de carregamento é exibida quando não temos dados para mostrar. Dito isso, terminamos com os 8 passos simples para começar a testar suas aplicações em React. </p><p><strong><em>Não tenha mais medo de testar.</em></strong></p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/200w_d.gif" class="kg-image" alt="200w_d" width="200" height="112" loading="lazy"></figure><h2 id="conclus-o">Conclusão</h2><p>A React Testing Library é um ótimo pacote para testar aplicações em React. Ela nos dá acesso aos <em>matchers</em> do jest-dom que podemos usar para testar nossos componentes de maneira mais eficiente e com boas práticas.</p><p>Espero que este artigo tenha sido útil e que ajude você a criar aplicações em React robustas no futuro. </p><p>Você pode encontrar o projeto finalizado <a href="https://github.com/ibrahima92/react-testing-library-guide">aqui</a>. </p><p><em>Obrigado pela leitura!</em></p><p><a href="https://www.ibrahima-ndaw.com/">Leia mais artigos do autor</a> – <a href="https://ibrahima-ndaw.us5.list-manage.com/subscribe?u=8dedf5d07c7326802dd81a866&amp;id=5d7bcd5b75">Inscreva-se na newsletter do autor</a> – <a href="https://twitter.com/ibrahima92_">Siga o autor no Twitter</a></p><p>Você pode ler outros artigos como este no <a href="https://www.ibrahima-ndaw.com/blog/react-testing-library-guide/">blog do autor</a>.</p><h2 id="pr-ximos-passos-documenta-es-em-ingl-s-">Próximos passos (documentações em inglês)</h2><p><a href="https://testing-library.com/docs/react-testing-library/intro">Documentação da React Testing Library</a></p><p><a href="https://testing-library.com/docs/react-testing-library/cheatsheet">Ficha informativa da React Testing Library</a></p><p><a href="https://github.com/testing-library/jest-dom">Ficha informativa dos matchers do Jest DOM</a></p><p><a href="https://jestjs.io/docs/en/getting-started.html">Documentação do Jest</a></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Aprenda a criar uma aplicação de bate-papo em React em 10 minutos – um tutorial de React ]]>
                </title>
                <description>
                    <![CDATA[ Clique aqui para acessar o curso completo [https://scrimba.com/g/greactchatkit?utm_source=freecodecamp.org&utm_medium=referral&utm_campaign=greactchatkit_10_minute_article]  (em inglês) no qual este artigo é baseado.Neste artigo, mostrarei a maneira mais fácil possível de se criar uma aplicação de bate-papo usando o React.js. Isso será feito totalmente sem código do lado do servidor, pois deixaremos a API do Chatkit ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/aprenda-a-criar-uma-aplicacao-de-bate-papo-em-react-em-10-minutos-um-tutorial-de-react/</link>
                <guid isPermaLink="false">65ccc78041193b03f653ffa4</guid>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Caroline Andrade ]]>
                </dc:creator>
                <pubDate>Tue, 28 May 2024 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_SUeSr13iO7yJfIf4ipaeFg.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/how-to-build-a-react-js-chat-app-in-10-minutes-c9233794642b/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Learn to build a React chat app in 10 minutes - React JS tutorial</a>
      </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_NE_xQlf9WZkO3LTpxG5TNA.png" class="kg-image" alt="1_NE_xQlf9WZkO3LTpxG5TNA" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/1_NE_xQlf9WZkO3LTpxG5TNA.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_NE_xQlf9WZkO3LTpxG5TNA.png 800w" sizes="(min-width: 720px) 720px" width="800" height="459" loading="lazy"><figcaption><a href="https://scrimba.com/g/greactchatkit?utm_source=freecodecamp.org&amp;utm_medium=referral&amp;utm_campaign=greactchatkit_10_minute_article">Clique aqui para acessar o curso completo</a> (em inglês) no qual este artigo é baseado.</figcaption></figure><p>Neste artigo, mostrarei a maneira mais fácil possível de se criar uma aplicação de bate-papo usando o React.js. Isso será feito totalmente sem código do lado do servidor, pois deixaremos a API do Chatkit cuidar do back-end.</p><p>Presumo que você saiba o básico de JavaScript e que já tenha visto um pouco de React.js antes. Fora isso, não há pré-requisitos.</p><p>Observação: também criei um curso completo e gratuito sobre como criar uma aplicação de bate-papo React.js <a href="https://scrimba.com/g/greactchatkit?utm_source=freecodecamp.org&amp;utm_medium=referral&amp;utm_campaign=greactchatkit_10_minute_article">aqui</a>.</p><p>Se seguir este tutorial, você terá sua própria aplicação de bate-papo no final, que poderá ser melhorada posteriormente, se desejar.</p><p>Vamos começar!</p><h3 id="etapa-1-divis-o-da-interface-do-usu-rio-ui-em-componentes">Etapa 1: divisão da interface do usuário (UI) em componentes</h3><p>O React foi desenvolvido com base em componentes. Portanto, a primeira coisa que você deve fazer ao criar uma aplicação é dividir a interface do usuário em componentes.</p><p>Vamos começar desenhando um retângulo ao redor de toda a aplicação. Esse é o componente raiz e o ancestral comum de todos os outros componentes. Vamos chamá-lo de <code>App</code>:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_66jz6LtljJtOPDouK9PmYA.png" class="kg-image" alt="1_66jz6LtljJtOPDouK9PmYA" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/1_66jz6LtljJtOPDouK9PmYA.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/05/1_66jz6LtljJtOPDouK9PmYA.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/05/1_66jz6LtljJtOPDouK9PmYA.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_66jz6LtljJtOPDouK9PmYA.png 1940w" sizes="(min-width: 720px) 720px" width="1940" height="810" loading="lazy"></figure><p>Depois de definir o componente raiz, você precisa se fazer a seguinte pergunta:</p><p>Quais filhos diretos esse componente tem?</p><p>No nosso caso, faz sentido dar a ele três componentes filhos, que chamaremos de:</p><ul><li><code>Title</code> (Título)</li><li><code>MessagesList</code> (Lista de mensagens)</li><li><code>SendMessageForm</code> (Formulário de envio de mensagens)</li></ul><p>Vamos desenhar um retângulo para cada um deles:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_SUeSr13iO7yJfIf4ipaeFg--1-.png" class="kg-image" alt="1_SUeSr13iO7yJfIf4ipaeFg--1-" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/1_SUeSr13iO7yJfIf4ipaeFg--1-.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/05/1_SUeSr13iO7yJfIf4ipaeFg--1-.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/05/1_SUeSr13iO7yJfIf4ipaeFg--1-.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_SUeSr13iO7yJfIf4ipaeFg--1-.png 1940w" sizes="(min-width: 720px) 720px" width="1940" height="810" loading="lazy"></figure><p>Isso nos dá uma boa visão geral dos diferentes componentes e da arquitetura por trás da nossa aplicação.</p><p>Poderíamos ter continuado e nos perguntado quais são os filhos desses componentes. Assim, poderíamos ter dividido a interface do usuário em ainda mais componentes, por exemplo, transformando cada uma das mensagens em seus próprios componentes. No entanto, vamos parar por aqui por uma questão de simplicidade.</p><h3 id="etapa-2-configura-o-da-base-de-c-digo">Etapa 2: configuração da base de código</h3><p>Agora, precisamos configurar nosso repositório. Usaremos a estrutura mais simples possível: um arquivo *index.html * com links para um arquivo JavaScript e uma <em>stylesheet</em>. Também estamos importando o Chatkit SDK e o Babel, que é usado para transformar nosso JSX:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_YCcPOlQGBk-dP-UQnyLEMA.png" class="kg-image" alt="1_YCcPOlQGBk-dP-UQnyLEMA" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/1_YCcPOlQGBk-dP-UQnyLEMA.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/05/1_YCcPOlQGBk-dP-UQnyLEMA.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/05/1_YCcPOlQGBk-dP-UQnyLEMA.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_YCcPOlQGBk-dP-UQnyLEMA.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="644" loading="lazy"></figure><p>Aqui está um playground do Scrimba com o código final do tutorial. Recomendo que você o abra em uma nova guia e brinque com ele sempre que se sentir confuso.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_xmr7Z2oR1PwJvLq2sHuZbQ.png" class="kg-image" alt="1_xmr7Z2oR1PwJvLq2sHuZbQ" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/1_xmr7Z2oR1PwJvLq2sHuZbQ.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/05/1_xmr7Z2oR1PwJvLq2sHuZbQ.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_xmr7Z2oR1PwJvLq2sHuZbQ.png 1600w" sizes="(min-width: 720px) 720px" width="1600" height="802" loading="lazy"></figure><p>Como alternativa, você pode fazer o download do projeto do Scrimba como um arquivo .zip e executar um servidor simples para colocá-lo em funcionamento localmente.</p><h3 id="etapa-3-cria-o-do-componente-raiz"><strong>Etapa 3: criação do componente raiz</strong></h3><p>Com o repositório instalado, podemos começar a escrever algum código em React, o que faremos dentro do arquivo *index.js *.</p><p>Vamos começar pelo componente principal, <code>App</code>. Esse será nosso único componente "inteligente", pois tratará dos dados e da conexão com a API. Esta é a configuração básica para ele (antes de adicionarmos qualquer lógica):</p><pre><code class="language-jsx">    class App extends React.Component {
      
      render() {
        return (
          &lt;div className="app"&gt;
            &lt;Title /&gt;
            &lt;MessageList /&gt;
            &lt;SendMessageForm /&gt;
         &lt;/div&gt;
        )
      }
    }
</code></pre><p>Como você pode ver, ele simplesmente renderiza três filhos: os componentes <code>&lt;Title&gt;</code>,<code>&lt;MessageList&gt;</code>, e <code>&lt;SendMessageForm&gt;</code>.</p><p>No entanto, vamos torná-lo um pouco mais complexo, pois as mensagens de bate-papo precisarão ser armazenadas dentro do estado (em inglês, <em>state</em>) desse componente App. Isso nos permitirá acessar as mensagens por meio de <code>this.state.messages</code> e, assim, passá-las para outros componentes.</p><p>Começaremos com o uso de dados fictícios para que possamos entender o fluxo de dados da aplicação. Em seguida, trocaremos esses dados por dados reais da API do Chatkit.</p><p>Vamos criar uma variável <code>DUMMY_DATA</code>:</p><pre><code class="language-jsx">    const DUMMY_DATA = [
      {
        senderId: "perborgen",
        text: "who'll win?"
      },
      {
        senderId: "janedoe",
        text: "who'll win?"
      }
    ]
</code></pre><p>Em seguida, adicionaremos esses dados ao estado da aplicação e os passaremos para o componente MessageList como uma propriedade.</p><pre><code class="language-jsx">    class App extends React.Component {
      
      constructor() {
        super()
        this.state = {
           messages: DUMMY_DATA
        }
      }
      
      render() {
        return (
          &lt;div className="app"&gt;
            &lt;MessageList messages={this.state.messages}/&gt;
            &lt;SendMessageForm /&gt;
         &lt;/div&gt;
        )
      }
    }
</code></pre><p>Aqui, estamos inicializando o estado no <code>constructor</code> e também estamos passando <code>this.state.messages</code> para <code>MessageList</code>.</p><p>Observe que estamos chamando <code>super()</code> no construtor. Você deve fazer isso se quiser criar um componente com estado (em inglês, <em>stateful</em>).</p><h3 id="etapa-4-renderiza-o-de-mensagens-fict-cias"><strong>Etapa 4: renderização de mensagens fictícias</strong></h3><p>Vamos ver como podemos renderizar essas mensagens no componente MessageList. Veja como fica:</p><pre><code class="language-jsx">    class MessageList extends React.Component {
      render() {
        return (
          &lt;ul className="message-list"&gt;                 
            {this.props.messages.map(message =&gt; {
              return (
               &lt;li key={message.id}&gt;
                 &lt;div&gt;
                   {message.senderId}
                 &lt;/div&gt;
                 &lt;div&gt;
                   {message.text}
                 &lt;/div&gt;
               &lt;/li&gt;
             )
           })}
         &lt;/ul&gt;
        )
      }
    }
</code></pre><p>Esse é o chamado componente estúpido. Ele usa uma propriedade, <code>messages</code>, que contém um <em>array</em> de objetos. Então, estamos simplesmente renderizando as propriedades <code>text</code> e <code>senderId</code> dos objetos.</p><p>Com nossos dados fictícios fluindo para esse componente, ele renderizará o seguinte:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_Nf12vqc4Ti_GWY0FwqmQKw.png" class="kg-image" alt="1_Nf12vqc4Ti_GWY0FwqmQKw" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/1_Nf12vqc4Ti_GWY0FwqmQKw.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_Nf12vqc4Ti_GWY0FwqmQKw.png 916w" sizes="(min-width: 720px) 720px" width="916" height="234" loading="lazy"></figure><p>Portanto, agora temos a estrutura básica da nossa aplicação e também podemos renderizar mensagens. Excelente trabalho!</p><p><strong>Agora, vamos substituir nossos dados fictícios por mensagens reais de uma sala de bate-papo!</strong></p><h3 id="etapa-5-obten-o-de-chaves-de-api-do-chatkit"><strong>Etapa 5: obtenção de chaves de API do Chatkit</strong></h3><p>Para buscar mensagens, precisaremos nos conectar à API do Chatkit. Para isso, precisamos obter as chaves da API.</p><p>Neste ponto, quero incentivá-lo a seguir minhas etapas para que você possa colocar sua própria aplicação de bate-papo em funcionamento. Você pode usar meu <a href="https://scrimba.com/c/crVznf6?utm_source=freecodecamp.org&amp;utm_medium=referral&amp;utm_campaign=greactchatkit_10_minute_article">playground do Scrimba</a> para testar suas próprias chaves de API.</p><p>Comece criando uma conta gratuita <a href="https://dashboard.pusher.com/accounts/sign_up?utm_medium=Website&amp;utm_source=Homepage_Signup_CTA&amp;utm_campaign=Homepage_CTA">aqui</a>. Depois de fazer isso, você verá seu painel de controle. É aqui que você cria instâncias do Chatkit. Crie uma e dê a ela o nome que você quiser:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/image-72.png" class="kg-image" alt="image-72" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/image-72.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/05/image-72.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/05/image-72.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/image-72.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="1072" loading="lazy"></figure><p>Em seguida, você será direcionado para a instância recém-criada. Aqui, você precisará copiar quatro valores:</p><ul><li>O localizador de instâncias (<em>instance locator</em>)</li><li>O provedor do token de teste (<em>test token provider</em>)</li><li>O ID da sala (<em>room ID</em>)</li><li>O nome de usuário</li></ul><p>Começaremos com o <strong>localizador de instâncias</strong>:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_AkbH5NfvHfwHAxiun37k9g.png" class="kg-image" alt="1_AkbH5NfvHfwHAxiun37k9g" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/1_AkbH5NfvHfwHAxiun37k9g.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/05/1_AkbH5NfvHfwHAxiun37k9g.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_AkbH5NfvHfwHAxiun37k9g.png 1200w" sizes="(min-width: 720px) 720px" width="1200" height="645" loading="lazy"></figure><p><em>Você pode copiar usando o ícone no lado direito do localizador de instâncias.</em></p><p>Se você rolar a tela um pouco para baixo, encontrará o <strong>provedor do token de teste</strong>:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_uSvabQgYrppTGsWKXQsJSQ.png" class="kg-image" alt="1_uSvabQgYrppTGsWKXQsJSQ" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/1_uSvabQgYrppTGsWKXQsJSQ.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/05/1_uSvabQgYrppTGsWKXQsJSQ.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/05/1_uSvabQgYrppTGsWKXQsJSQ.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_uSvabQgYrppTGsWKXQsJSQ.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="1075" loading="lazy"></figure><p>O próximo passo é criar um <strong><strong>Us</strong>uário </strong>e uma <strong>Sala</strong>, o que é feito na mesma página. Observe que, <em>primeiro</em>, será necessário criar um usuário e, em seguida, você poderá criar uma sala, o que dará a você acesso ao identificador da sala.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_hCXjDJ3PQJ_emU4WfJRQEQ.png" class="kg-image" alt="1_hCXjDJ3PQJ_emU4WfJRQEQ" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/1_hCXjDJ3PQJ_emU4WfJRQEQ.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/05/1_hCXjDJ3PQJ_emU4WfJRQEQ.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/05/1_hCXjDJ3PQJ_emU4WfJRQEQ.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_hCXjDJ3PQJ_emU4WfJRQEQ.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="1193" loading="lazy"><figcaption>No segundo círculo vermelho, você vê o identificador da sala</figcaption></figure><p>Agora, você encontrou os seus quatro identificadores. Muito bem!</p><p>No entanto, antes de voltarmos à base de código, quero que você também envie manualmente uma mensagem do painel do Chatkit, pois isso nos ajudará no próximo capítulo.</p><p>Veja como fazer isso:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_HU3mzUknYj8_MwY7ceK2Ow.png" class="kg-image" alt="1_HU3mzUknYj8_MwY7ceK2Ow" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/1_HU3mzUknYj8_MwY7ceK2Ow.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/05/1_HU3mzUknYj8_MwY7ceK2Ow.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/05/1_HU3mzUknYj8_MwY7ceK2Ow.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_HU3mzUknYj8_MwY7ceK2Ow.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="1194" loading="lazy"></figure><p>Isso é para que tenhamos de fato uma mensagem para renderizar na próxima etapa.</p><h3 id="etapa-6-renderiza-o-de-mensagens-reais-de-bate-papo"><strong>Etapa 6: renderização de mensagens reais de bate-papo</strong></h3><p>Agora, vamos voltar ao nosso arquivo <em>index.js</em> e armazenar esses quatro identificadores como variáveis na parte superior do nosso arquivo.</p><p>Aqui estão as minhas, mas eu o encorajo a criar as suas próprias:</p><pre><code class="language-jsx">    const instanceLocator = "v1:us1:dfaf1e22-2d33-45c9-b4f8-31f634621d24"

    const testToken = "https://us1.pusherplatform.io/services/chatkit_token_provider/v1/dfaf1e22-2d33-45c9-b4f8-31f634621d24/token"

    const username = "perborgen"

    const roomId = 9796712
</code></pre><p>Com isso pronto, finalmente estamos prontos para nos conectar ao Chatkit. Isso ocorrerá no componente <code>App</code> e, mais especificamente, no método <code>componentDidMount</code>. Esse é o método que você deve usar ao conectar componentes React.js a APIs.</p><p>Primeiro, criaremos um <code>chatManager</code>:</p><pre><code class="language-jsx">    componentDidMount() {
      const chatManager = new Chatkit.ChatManager({
        instanceLocator: instanceLocator,
        userId: userId,
        tokenProvider: new Chatkit.TokenProvider({
          url: testToken
        })
     })  
</code></pre><p>Em seguida, usaremos <code>chatManager.connect()</code> para nos conectarmos à API:</p><pre><code class="language-jsx">      chatManager.connect().then(currentUser =&gt; {
          currentUser.subscribeToRoom({
          roomId: roomId,
          hooks: {
            onNewMessage: message =&gt; {
              this.setState({
                messages: [...this.state.messages, message]
              })
            }
          }
        })
      })
    }
</code></pre><p>Isso nos dá acesso ao objeto <code>currentUser</code>, que é a interface para interagir com a API.</p><p>Observação: como precisaremos usar o <code>currentUser</code> mais tarde, vamos armazená-lo na instância, com <code>this.currentUser = ``currentUser</code>.</p><p>Em seguida, chamamos <code>currentUser.subscribeToRoom()</code> e passamos a ele nosso <code>roomId</code> e um <em>hook</em> <code>onNewMessage</code>.</p><p>O <em>hook</em> <code>onNewMessage</code> é acionado toda vez que uma nova mensagem é transmitida para a sala de bate-papo. Portanto, toda vez que isso acontecer, simplesmente adicionaremos a nova mensagem no final de <code>this.state.messages</code>.</p><p>Isso faz com que a aplicação busque dados da API e depois os renderize na página.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_EAi9TyUba39xN3fciic3aA.png" class="kg-image" alt="1_EAi9TyUba39xN3fciic3aA" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/1_EAi9TyUba39xN3fciic3aA.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/05/1_EAi9TyUba39xN3fciic3aA.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_EAi9TyUba39xN3fciic3aA.png 1488w" sizes="(min-width: 720px) 720px" width="1488" height="776" loading="lazy"></figure><p>Isso é fantástico, pois agora temos o esqueleto da nossa conexão <em>client</em>-servidor.</p><p>Uau!</p><h3 id="etapa-7-manipula-o-de-entrada-do-usu-rio"><strong>Etapa 7: manipulação de entrada do usuário</strong></h3><p>A próxima coisa que precisaremos criar é o componente <code>SendMessageForm</code>. Esse será o chamado <em>componente controlado</em>, o que significa que o componente controla o que está sendo renderizado no campo de entrada por meio de seu estado.</p><p>Dê uma olhada no método <code>render()</code>:</p><pre><code class="language-jsx">    class SendMessageForm extends React.Component {
      render() {
        return (
          &lt;form
            className="send-message-form"&gt;
            &lt;input
              onChange={this.handleChange}
              value={this.state.message}
              placeholder="Type your message and hit ENTER"
              type="text" /&gt;
          &lt;/form&gt;
        )
      }
    }
</code></pre><p>Estamos fazendo duas coisas:</p><ol><li>Ouvir as entradas do usuário com o ouvinte de eventos <code>onChange</code>, de modo que possamos acionar o método <code>handleChange</code> </li><li>Definir o <code>value</code> do campo de entrada explicitamente usando <code>this.state.message</code></li></ol><p>A conexão entre essas duas etapas é encontrada dentro do método <code>handleChange</code>. Ele simplesmente atualiza o estado para o que quer que o usuário digite no campo de entrada:</p><pre><code class="language-jsx">    handleChange(e) {
      this.setState({
        message: e.target.value
      })
    }
</code></pre><p>Isso aciona uma nova renderização e, como o campo de entrada é definido explicitamente a partir do estado usando <code>value={this.state.message}</code>, &nbsp;o campo de entrada será atualizado.</p><p>Portanto, mesmo que a aplicação pareça instantânea para o usuário quando ele digita algo no campo de entrada, <strong>os dados realmente passam pelo estado antes que o React atualize a interface do usuário.</strong></p><p>Para encerrar esse recurso, precisamos dar ao componente um <code>constructor</code>. Nele, inicializaremos o estado e vincularemos <code>this</code> no método <code>handleChange</code>:</p><pre><code class="language-jsx">    constructor() {
        super()
        this.state = {
           message: ''
        }
        this.handleChange = this.handleChange.bind(this)
    }
</code></pre><p>Precisamos vincular o método <code>handleChange</code> para que tenhamos acesso à palavra-chave <code>this</code> dentro dele. É assim que o JavaScript funciona: a palavra-chave <code>this</code> é, por padrão, <em>indefinida</em> dentro do corpo de uma função.</p><h3 id="etapa-8-envio-de-mensagens"><strong>Etapa 8: envio de mensagens</strong></h3><p>Nosso componente <code>SendMessageForm</code> está quase pronto, mas também precisamos cuidar do envio do formulário. Precisamos buscar as mensagens e enviá-las!</p><p>Para fazer isso, conectaremos um manipulador uniforme <code>handleSubmit</code> ao ouvinte de eventos <code>onSubmit</code> no <code>&lt;form&gt;</code>.</p><pre><code class="language-jsx">    render() {
        return (
          &lt;form
            onSubmit={this.handleSubmit}
            className="send-message-form"&gt;
            &lt;input
              onChange={this.handleChange}
              value={this.state.message}
              placeholder="Type your message and hit ENTER"
              type="text" /&gt;
        &lt;/form&gt;
        )
      }
</code></pre><p>Como temos o valor do campo de entrada armazenado em <code>this.state.message</code>, é muito fácil passar os dados corretos junto com o envio. Basta fazer isso:</p><pre><code class="language-jsx">    handleSubmit(e) {
      e.preventDefault()
      this.props.sendMessage(this.state.message)
      this.setState({
        message: ''
      })
    }
</code></pre><p>Aqui, estamos chamando a propriedade <code>sendMessage</code> e passando <code>this.state.message</code> como parâmetro. Talvez você esteja um pouco confuso com isso, pois ainda não criamos o método <code>sendMessage</code>. No entanto, faremos isso na próxima seção, pois esse método está dentro do componente <code>App</code>. Portanto, não se preocupe!</p><p>Em segundo lugar, estamos limpando o campo de entrada definindo <code>this.state.message</code> como uma <em>string </em>vazia.</p><p>Aqui está o componente <code>SendMessageForm</code> completo. Observe que também vinculamos o <code>this</code> ao método <code>handleSubmit</code>:</p><pre><code class="language-jsx">    class SendMessageForm extends React.Component {
      constructor() {
        super()
        this.state = {
          message: ''
        }
        this.handleChange = this.handleChange.bind(this)
        this.handleSubmit = this.handleSubmit.bind(this)
      }

      handleChange(e) {
        this.setState({
          message: e.target.value
        })
      }

      handleSubmit(e) {
        e.preventDefault()
        this.props.sendMessage(this.state.message)
        this.setState({
          message: ''
        })
      }

      render() {
        return (
          &lt;form
            onSubmit={this.handleSubmit}
            className="send-message-form"&gt;
            &lt;input
              onChange={this.handleChange}
              value={this.state.message}
              placeholder="Type your message and hit ENTER"
              type="text" /&gt;
          &lt;/form&gt;
        )
      }
    }
</code></pre><h3 id="etapa-9-envio-de-mensagens-para-o-chatkit"><strong>Etapa 9: envio de mensagens para o Chatkit</strong></h3><p>Agora, estamos prontos para enviar as mensagens para o Chatkit. Isso é feito no componente <code>App</code>, onde criaremos um método chamado <code>this.sendMessage</code>:</p><pre><code class="language-jsx">    sendMessage(text) {
      this.currentUser.sendMessage({
        text: text,
        roomId: roomId
      })
    }
</code></pre><p>Ele recebe um parâmetro (o texto) e simplesmente chama <code>this.currentUser.sendMessage()</code>.</p><p>A etapa final é passar isso para o componente <code>&lt;SendMessageForm&gt;</code> como uma propriedade:</p><pre><code class="language-jsx">    /* App component */
      
    render() {
      return (
        &lt;div className="app"&gt;
          &lt;Title /&gt;
          &lt;MessageList messages={this.state.messages} /&gt;
          &lt;SendMessageForm sendMessage={this.sendMessage} /&gt;
      )
    }
</code></pre><p>Com isso, passamos o manipulador para que <code>SendMessageForm</code> possa invocá-lo quando o formulário for enviado.</p><h3 id="etapa-10-criando-o-componente-title"><strong>Etapa 10: criando o componente Title</strong></h3><p>Para finalizar, vamos criar também o componente Title. Ele é apenas um componente funcional simples, ou seja, uma função que retorna uma expressão JSX.</p><pre><code class="language-jsx">    function Title() {
      return &lt;p class="title"&gt;My awesome chat app&lt;/p&gt;
    }
</code></pre><p>É uma boa prática usar componentes funcionais, pois eles têm mais restrições do que os componentes de classe, o que os torna menos propensos a <em>bugs</em>.</p><h3 id="o-resultado">O resultado</h3><p>Com isso, você tem sua própria aplicação de bate-papo, que pode ser usada para conversar com seus amigos!</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_KQzdlJJLMGyq5IdZu6cZ1Q.png" class="kg-image" alt="1_KQzdlJJLMGyq5IdZu6cZ1Q" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/1_KQzdlJJLMGyq5IdZu6cZ1Q.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/05/1_KQzdlJJLMGyq5IdZu6cZ1Q.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_KQzdlJJLMGyq5IdZu6cZ1Q.png 1490w" sizes="(min-width: 720px) 720px" width="1490" height="776" loading="lazy"></figure><p>Dê a si mesmo um tapinha nas costas se tiver programado toda a aplicação até o fim.</p><p>Se você quiser saber como desenvolver esse exemplo, <a href="https://scrimba.com/g/greactchatkit?utm_source=freecodecamp.org&amp;utm_medium=referral&amp;utm_campaign=greactchatkit_10_minute_article">então confira meu curso gratuito sobre como criar uma aplicação de bate-papo</a> com o React aqui.</p><p>Obrigado pela leitura e boa programação! 😀</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ React – mudar o CSS em linha condicionalmente com base no estado do componente ]]>
                </title>
                <description>
                    <![CDATA[ Se você estiver com problemas com o desafio Mudar CSS em linha condicionalmente com base no estado do componente [https://www.freecodecamp.org/portuguese/learn/front-end-development-libraries/react/change-inline-css-conditionally-based-on-component-state]  do freeCodeCamp, provavelmente, não está sozinho. Nesse desafio, você precisa adicionar código para alterar de modo condicional o CSS em linha com base no estado, ou state, de um ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/react-mudar-o-css-em-linha-condicionalmente-com-base-no-estado-do-componente/</link>
                <guid isPermaLink="false">66395d720e369603f905e9fb</guid>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Daniel Rosa ]]>
                </dc:creator>
                <pubDate>Mon, 06 May 2024 23:09:45 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/5f9c9a95740569d1a4ca267a.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/react-change-inline-css-conditionally-based-on-component-state/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">React - Change Inline CSS Conditionally Based on Component State</a>
      </p><p>Se você estiver com problemas com o desafio <a href="https://www.freecodecamp.org/portuguese/learn/front-end-development-libraries/react/change-inline-css-conditionally-based-on-component-state">Mudar CSS em linha condicionalmente com base no estado do componente</a> do freeCodeCamp, provavelmente, não está sozinho.</p><p>Nesse desafio, você precisa adicionar código para alterar de modo condicional o CSS em linha com base no estado, ou <em>state</em>, de um componente do React.</p><p>Ao chegar ao desafio, este é o código que você verá:</p><pre><code class="language-jsx">class GateKeeper extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      input: ''
    };
    this.handleChange = this.handleChange.bind(this);
  }
  handleChange(event) {
    this.setState({ input: event.target.value })
  }
  render() {
    let inputStyle = {
      border: '1px solid black'
    };
    // Altere o código abaixo desta linha

    // Altere o código acima desta linha
    return (
      &lt;div&gt;
        &lt;h3&gt;Don't Type Too Much:&lt;/h3&gt;
        &lt;input
          type="text"
          style={inputStyle}
          value={this.state.input}
          onChange={this.handleChange} /&gt;
      &lt;/div&gt;
    );
  }
};
</code></pre><p>Perceba que um objeto de estilo em linha, chamado <code>inputStyle</code>, já foi declarado com estilização padrão.</p><p>Seu objetivo nesse desafio é atualizar <code>inputStyle</code> de maneira que a borda do elemento <code>input</code> seja <code>3px solid red</code> quando houver mais de 15 caracteres na entrada. Observe que o texto na caixa de entrada é salvo no <em>state</em> do componente como <code>input</code>:</p><pre><code class="language-jsx">...
this.state = {
  input: ''
};
...</code></pre><h2 id="quase-l-mas-ainda-n-o-est-certo"><strong>Quase lá, mas ainda não está certo</strong></h2><p>Imagine que, após ler a descrição e as instruções, você tenha essa ideia:</p><pre><code class="language-jsx">class GateKeeper extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      input: ''
    };
    this.handleChange = this.handleChange.bind(this);
  }
  handleChange(event) {
    this.setState({ input: event.target.value })
  }
  render() {
    let inputStyle = {
      border: '1px solid black'
    };
    // Altere o código abaixo desta linha
    const char = 15;
    if(this.state.input &gt; char) {
      inputStyle = {
        border:'3px solid red'
      }
    }  
    // Altere o código acima desta linha
    return (
      &lt;div&gt;
        &lt;h3&gt;Don't Type Too Much:&lt;/h3&gt;
        &lt;input
          type="text"
          style={inputStyle}
          value={this.state.input}
          onChange={this.handleChange} /&gt;
      &lt;/div&gt;
    );
  }
};</code></pre><p>Ao tentar enviar, porém, o código não passa em todos os testes. Vamos examinar mais de perto o que está havendo.</p><h2 id="solu-es"><strong>Soluções</strong></h2><h3 id="usando-uma-instru-o-if"><strong>Usando uma instrução <code>if</code></strong></h3><p>Declarar <code>char</code> é uma boa ideia, mas examine a condição no bloco <code>if</code>:</p><pre><code class="language-jsx">if(this.state.input &gt; char) {
  inputStyle = {
    border:'3px solid red'
  }
}  </code></pre><p>Lembre-se de que <code>this.state.input</code> é o valor da caixa de entrada e que é uma <em>string</em>. Por exemplo, ela pode ser "testando testando 1, 2, 3".</p><p>Se você inserir "testando testando 1, 2, 3" na caixa de texto e se registrar <code>this.state.input</code> no console (usando <code>console.log</code>):</p><pre><code class="language-jsx">class GateKeeper extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      input: ''
    };
    this.handleChange = this.handleChange.bind(this);
  }
  handleChange(event) {
    this.setState({ input: event.target.value })
  }
  render() {
    let inputStyle = {
      border: '1px solid black'
    };
    // Altere o código abaixo desta linha
    const char = 15;
    console.log(this.state.input);
    if(this.state.input &gt; char) {
      inputStyle = {
        border:'3px solid red'
      }
    }  
    // Altere o código acima desta linha
    return (
      &lt;div&gt;
        &lt;h3&gt;Don't Type Too Much:&lt;/h3&gt;
        &lt;input
          type="text"
          style={inputStyle}
          value={this.state.input}
          onChange={this.handleChange} /&gt;
      &lt;/div&gt;
    );
  }
};</code></pre><p>Você verá <code>testando testando 1, 2, 3</code> no console.</p><p>Além disso, se você registrar <code>this.state.input &gt; char</code> no console, verá que seu valor é <code>false</code>:</p><pre><code class="language-jsx">class GateKeeper extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      input: ''
    };
    this.handleChange = this.handleChange.bind(this);
  }
  handleChange(event) {
    this.setState({ input: event.target.value })
  }
  render() {
    let inputStyle = {
      border: '1px solid black'
    };
    // Altere o código abaixo desta linha
    const char = 15;
    console.log(this.state.input &gt; char);
    if(this.state.input &gt; char) {
      inputStyle = {
        border:'3px solid red'
      }
    }  
    // Altere o código acima desta linha
    return (
      &lt;div&gt;
        &lt;h3&gt;Don't Type Too Much:&lt;/h3&gt;
        &lt;input
          type="text"
          style={inputStyle}
          value={this.state.input}
          onChange={this.handleChange} /&gt;
      &lt;/div&gt;
    );
  }
};</code></pre><p>Dito de maneira simplificada, não é possível comparar uma <em>string</em> (<code>this.state.input</code>) diretamente com <code>char</code>, que é um número.</p><p>Em vez disso, chame <code>.length</code> em <code>this.state.input</code> para obter o tamanho da <em>string</em> e compare-o a <code>count</code>:</p><pre><code class="language-jsx">class GateKeeper extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      input: ''
    };
    this.handleChange = this.handleChange.bind(this);
  }
  handleChange(event) {
    this.setState({ input: event.target.value })
  }
  render() {
    let inputStyle = {
      border: '1px solid black'
    };
    // Altere o código abaixo desta linha
    const char = 15;
    if(this.state.input.length &gt; char) {
      inputStyle = {
        border:'3px solid red'
      }
    }  
    // Altere o código acima desta linha
    return (
      &lt;div&gt;
        &lt;h3&gt;Don't Type Too Much:&lt;/h3&gt;
        &lt;input
          type="text"
          style={inputStyle}
          value={this.state.input}
          onChange={this.handleChange} /&gt;
      &lt;/div&gt;
    );
  }
};</code></pre><p>Como o tamanho da <em>string</em> "testando testando 1, 2, 3" é de 23 caracteres (incluindo espaços e vírgulas), a borda da caixa de entrada deverá ser vermelha:</p><h3 id="usando-um-operador-tern-rio"><strong>Usando um operador ternário</strong></h3><p>Um <a href="https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Operators/Conditional_Operator">operador ternário ou condicional</a> é como uma instrução <code>if...else</code> de apenas uma linha, o que pode ajudar você a reduzir significativamente o tamanho do seu código.</p><p>Volte agora à sua solução e remova tudo, exceto a variável <code>char</code>:</p><pre><code class="language-jsx">class GateKeeper extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      input: ''
    };
    this.handleChange = this.handleChange.bind(this);
  }
  handleChange(event) {
    this.setState({ input: event.target.value })
  }
  render() {
    let inputStyle = {
      border: '1px solid black'
    };
    // Altere o código abaixo desta linha

    // Altere o código acima desta linha
    return (
      &lt;div&gt;
        &lt;h3&gt;Don't Type Too Much:&lt;/h3&gt;
        &lt;input
          type="text"
          style={inputStyle}
          value={this.state.input}
          onChange={this.handleChange} /&gt;
      &lt;/div&gt;
    );
  }
};
</code></pre><p>Agora, pegue a condição que você usou na sua instrução <code>if</code> de antes e use-a na primeira parte do operador ternário: <code>this.state.input.length &gt; char ? &nbsp;: &nbsp;;</code></p><p>Tudo o que estiver entre <code>?</code> e <code>:</code> indica o que ocorrerá se a instrução retornar <code>true</code>. Você pode simplesmente copiar o código que estava dentro da instrução <code>if</code> de antes: <code>this.state.input.length &gt; char ? inputStyle = { border:'3px solid red' } : &nbsp;;</code></p><p>Depois disso, você precisa lidar com a parte do <code>else</code> do operador ternário, que é tudo o que se encontra entre <code>:</code> e <code>;</code>.</p><p>Embora você não tenha usado uma instrução <code>else</code> na sua primeira solução, você conseguiu usar <code>inputStyle</code> como estava de modo eficaz. Assim, basta usar <code>inputStyle</code> do modo como foi declarado anteriormente no código: <code>this.state.input.length &gt; char ? inputStyle = { border:'3px solid red' } : inputStyle;</code></p><p>Sua solução completa deverá ter esta aparência:</p><pre><code class="language-jsx">class GateKeeper extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      input: ''
    };
    this.handleChange = this.handleChange.bind(this);
  }
  handleChange(event) {
    this.setState({ input: event.target.value })
  }
  render() {
    let inputStyle = {
      border: '1px solid black'
    };
    // Altere o código abaixo desta linha
    const char = 15;
    this.state.input.length &gt; char ? inputStyle = { border:'3px solid red' } : inputStyle;
    // Altere o código acima desta linha
    return (
      &lt;div&gt;
        &lt;h3&gt;Don't Type Too Much:&lt;/h3&gt;
        &lt;input
          type="text"
          style={inputStyle}
          value={this.state.input}
          onChange={this.handleChange} /&gt;
      &lt;/div&gt;
    );
  }
};
</code></pre><p>Está resolvido – agora, você deve ser capaz de passar no desafio! Agora, você já sabe como estilizar de modo condicional os componentes do React da maneira que quiser.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como implementar uma aplicação do React em produção usando Docker, NGINX e APIs ]]>
                </title>
                <description>
                    <![CDATA[ Neste artigo, você vai aprender como implementar (eminglês, deploy) uma aplicação desenvolvida com React em produção. Vamos utilizar o Docker e o NGINX para assegurar nossas chaves de acesso da API e requisições de proxy, a fim de prevenir ataques de Cross-Origin Resource Sharing [https://pt.wikipedia.org/wiki/Cross-origin_resource_sharing] (CORS). No final do artigo, ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-implementar-uma-aplicacao-do-react-em-producao-usando-docker-nginx-e-apis/</link>
                <guid isPermaLink="false">642f6ac286dbbe0599dbb2ca</guid>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Diego Crescêncio ]]>
                </dc:creator>
                <pubDate>Sun, 21 Apr 2024 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/fringer-cat-hddmXlPaFGo-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/how-to-deploy-react-apps-to-production/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Deploy a React App to Production Using Docker and NGINX with API Proxies</a>
      </p><p>Neste artigo, você vai aprender como implementar (eminglês, <em>deploy</em>) uma aplicação desenvolvida com React em produção. Vamos utilizar o Docker e o NGINX para assegurar nossas chaves de acesso da API e requisições de proxy, a fim de prevenir ataques de <a href="https://pt.wikipedia.org/wiki/Cross-origin_resource_sharing">Cross-Origin Resource Sharing</a> (CORS).</p><p>No final do artigo, você pode conferir o código e um vídeo relacionado.</p><h3 id="o-que-voc-vai-aprender-neste-artigo">O que você vai aprender neste artigo</h3><p>Em todo ciclo de vida do projeto de software, chega a hora de publicá-lo. Porém, nem sempre é óbvio como fazê-lo. O ambiente de produção é diferente do ambiente de desenvolvimento. A maioria das aplicações consome algum tipo de API – por vezes, hospedada em diferentes servidores.</p><p>Como desenvolvedores, precisamos resolver potenciais riscos de CORS. Às vezes, acabamos construindo um <em>back-end</em> desnecessariamente. Eu acredito que desenvolvedores devem manter suas aplicações simples, cortando todas as partes redundantes.</p><p>Neste artigo, vou mostrar como eu preparo minhas aplicações desenvolvidas em React para implantar em produção. </p><p>Eu poderia demonstrar uma aplicação simples, mas isso seria pouco útil. Portanto, decidi criar uma aplicação que consome dados de uma API real, a fornecida pela <a href="https://fred.stlouisfed.org/docs/api/fred/">Divisão de Pesquisa Econômica do Federal Reserve Bank of Saint Louis</a>. A API requer uma chave de acesso para obter dados, e os <em>endpoints</em> estão protegidos contra vulnerabilidades de CORS.</p><p><strong>Observação</strong>: se sua aplicação é baseada em rederização no servidor (SSR, em inglês, <em>server-side rendering</em>), <strong>esta não é a melhor estratégia de implantação</strong>. Você, provavelmente, precisará de algum tipo de <em>back-end</em>.</p><h2 id="pr-requisitos">Pré-requisitos</h2><p>É importante que você tenha conhecimento básico de como construir aplicações em React e conheça os fundamentos de Docker antes de seguir as instruções deste artigo. Caso você precise revisar esses conteúdos, acesse esses conteúdos do FreeCodeCamp (ambos em inglês):</p><ul><li><a href="https://www.freecodecamp.org/news/a-beginner-friendly-introduction-to-containers-vms-and-docker-79a9e3e119b/">A Beginner-Friendly Introduction to Containers, VMs and Docker</a>, de <a href="https://twitter.com/iam_preethi">@iam_preethi</a></li><li><a href="https://www.freecodecamp.org/news/create-react-app-crash-course/">Create React App Crash Course</a></li></ul><h2 id="construindo-a-aplica-o-em-react">Construindo a aplicação em React</h2><p>Eu criei uma aplicação simples usando o comando <a href="https://legacy.reactjs.org/docs/create-a-new-react-app.html#create-react-app">create-react-app</a>. A única funcionalidade da aplicação será exibir um gráfico que representa o produto interno bruto (PIB) dos Estados Unidos da América.</p><p><strong>Observação:</strong> &nbsp;a documentação legada do React recomenda o uso do <em>create-react-app</em> para aplicações de página única (SPA– do inglês, <em>single page applications</em>) ou para quem esta aprendendo React.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/fredapp.png" class="kg-image" alt="fredapp" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/04/fredapp.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/04/fredapp.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/04/fredapp.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/04/fredapp.png 2276w" sizes="(min-width: 1200px) 1200px" width="2276" height="1600" loading="lazy"></figure><p>A aplicação obtém dados somente desta API:</p><pre><code>https://api.stlouisfed.org/fred/series/observations?series_id=GDPCA&amp;frequency=a&amp;observation_start=1999-04-15&amp;observation_end=2021-01-01&amp;file_type=json&amp;api_key=abcdefghijklmnopqrstuvwxyz123456</code></pre><p>Os parametros são:</p><ul><li><code>series_id</code> – o identificador das séries. <code>GDPCA</code> se refere à "GDP real".</li><li><code>frequency</code> – a agregação do dado. O <code>a</code> se refere à "anual".</li><li><code>observation_start</code> – o início do período observado.</li><li><code>observation_end</code> – o fim do período observado.</li><li><code>file_type</code> – o formato do dado. O padrão é <code>xml</code>.</li><li><code>api_key</code> – A chave da API é requerida para obter dados. Você pode solicitar uma chave de acesso aqui: <a href="https://fred.stlouisfed.org/docs/api/api_key.html">veja uma aqui</a>.</li></ul><p>Para mais detalhes, consulte a <a href="https://fred.stlouisfed.org/docs/api/fred/series_observations.html">documentação</a>.</p><p>Como nem tudo é perfeito, o projeto da API também não é. Nessa API, é necessário que o desenvolvedor envie a chave de acesso e o retorno vem como parâmetros de URL.</p><p>Enviar o código como parâmetro não é um problema para nós. Entretanto, o vazamento da chave da API pode ser um problema! Imagine que alguém pode interceptar a busar da API, realizando procedimentos abusivos. Ninguém quer correr esse risco, certo?</p><p>Vamos assumir que a chave da API não é um problema. Ainda assim, é possível abusar da API. A API FRED tem proteção contra requisições interdomínio (do inglês, <em>cross-domain request</em>). Portanto, você obtém os seguintes erros se tentar acessá-la de um domínio externo:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/frederror.png" class="kg-image" alt="frederror" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/04/frederror.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/04/frederror.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/04/frederror.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w2400/2024/04/frederror.png 2400w" sizes="(min-width: 1200px) 1200px" width="2440" height="1710" loading="lazy"></figure><p>Muitos desenvolvedores podem sugerir o emprego de uma aplicação intermediária (<em>middleware</em>) para requisitar a API e filtrar conteúdo sensível via proxy. Podem dizer que precisam ampliar as funcionalidades futuras e, de certa maneira, essa é uma boa abordagem.</p><p>Entretanto, eu prefiro construir minhas aplicações seguindo um dos princípios da vertente da <a href="https://pt.wikipedia.org/wiki/Programação_extrema">Programação Extrema</a> (do inglês, <em>Extreme Programming</em>). Um dos tantos princípios se trata de "você não vai precisar disso", que prega evitar a adição de muitas funcionalidades, principalmente as que "você talvez nunca use" (<a href="https://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it">YAGNI way</a>). Portanto, vou evitar construir um <em>back-end</em> até ser necessário, ou no nosso caso, "nunca ser necessário".</p><h2 id="vamos-usar-o-nginx-">Vamos usar o NGINX!</h2><p>Eu sou fã do <a href="https://www.nginx.com">NGINX</a> porque ele traz a simplicidade de uso. O NGINX permite que você prepare um servidor web de nível de produção, com funcionalidade HTTP2, compressão, TLS etc.</p><p>Podemos chegar a configurações robustas com poucas linhas de código. Veja o exemplo abaixo:</p><pre><code class="language-none">...

http {
    ...

    server {
        ...

        location /api {
            set         $args   $args&amp;&amp;file_type=json&amp;api_key=abcdefghijklmnopqrstuvwxyz123456;
            proxy_pass  https://api.stlouisfed.org/fred/series;
        }
    }
}</code></pre><p>Essas quatro linhas de código são todo o necessário para ocultar nossa chave API e suprimir errros de CORS. Agora, todo o tráfego HTTP para <code>/api</code> será enviado para a FRED API e apenas a nossa aplicação esta habilitada a consumir estes dados. Todas as outras requisições externas vão obter erro de CORS.</p><blockquote>Para se livrar dos excessos, eu troquei todo o conteúdo do arquivo por <code>...</code>. Você pode encontrar a versão completa no meu <strong>GitHub </strong><em>ou no</em><strong> vídeo </strong>(links abaixo).</blockquote><p>Agora, nosso ponto de acesso (<em>endpoint</em>) é: </p><pre><code>/api/observations?series_id=GDPCA&amp;frequency=a&amp;observation_start=1999-04-15&amp;observation_end=2021-01-01</code></pre><p>Agora não é necessário passar os parâmetros <code>api_key</code> nem <code>file_type</code> para obter dados. Além disso, ninguém pode acessar a chave de acesso a partir do URL, o que torna o processo seguro.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/Screen-Shot-2021-03-14-at-12.49.55.png" class="kg-image" alt="Screen-Shot-2021-03-14-at-12.49.55" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/04/Screen-Shot-2021-03-14-at-12.49.55.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/04/Screen-Shot-2021-03-14-at-12.49.55.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/04/Screen-Shot-2021-03-14-at-12.49.55.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/04/Screen-Shot-2021-03-14-at-12.49.55.png 2072w" sizes="(min-width: 1200px) 1200px" width="2072" height="790" loading="lazy"></figure><h2 id="o-docker-prefere-o-nginx-">O Docker prefere o NGINX!</h2><p>A maneira mais conveniente de executar o NGINX na nuvem é usando o Docker. Para essa parte, assumo que você saiba o que é o Docker (mas se não souber, leia o artigo vinculado nos pré-requisitos). <br>Antes, precisamos criar um Dockerfile com o seguinte conteúdo:</p><pre><code class="language-dockerfile">FROM nginx

COPY container /
COPY build /usr/share/nginx/html</code></pre><p>Agora só restam esses três passos:</p><ol><li>Construir a aplicação em React. Esse processo gera o diretório <code>build/</code>, contendo os arquivos estáticos.</li><li>Construir a imagem do Docker. Isso criará uma imagem do Docker executável.</li><li>Publicar a imagem do Docker em algum repositório ou executá-la localmente. </li></ol><p>Por enquanto, vamos tentar executá-la em nossa máquina.</p><pre><code>$ yarn install
$ yarn build
$ docker build -t msokola/fred-app:latest .
$ docker run -p 8081:80 -it msokola/fred-app:latest</code></pre><p>A porta 8081 é uma porta local e em sua máquina. Isso significa que a aplicação estará disponível no seguinte URL: <a href="http://localhost:8081/">http://localhost:8081</a>. </p><p>Após abrir esse URL no navegador, você deve ver registros como estes em seu terminal:</p><pre><code>0.0.0.1 - - [11/Mar/2021:18:57:50 +0000] "GET / HTTP/1.1" 200 1556 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.192 Safari/537.36" "-"
...
0.0.0.1 - - [11/Mar/2021:18:57:51 +0000] "GET /api/observations?series_id=GDPCA&amp;frequency=a&amp;observation_start=1999-04-15&amp;observation_end=2021-01-01 HTTP/1.1" 200 404 "http://localhost:8081/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.192 Safari/537.36" "-"</code></pre><p>Observe os códigos 200, pois eles representam o status HTTP OK. Se você vir um 400 ao lado da solicitação da API, significa que algo está errado com sua chave de API. O código 304 também é válido (isso significa que os dados foram armazenados em cache).</p><h2 id="como-fazer-o-deploy-do-cont-iner-na-aws">Como fazer o <em>deploy </em>do contêiner na AWS</h2><p>O contêiner está funcionando, então podemos implementá-lo. Nessa parte do artigo, vou mostrar como executar sua aplicação na Amazon Web Services (AWS). A AWS é uma das plataformas de nuvem mais populares. Se você deseja usar o Microsoft Azure ou qualquer outra plataforma, os passos serão semelhantes, mas a sintaxe dos comandos será diferente. </p><p><strong>Observação</strong>: gravei um vídeo no YouTube para que você possa me ver passando por todo o processo de implantação. Se você ficar preso ou encontrar problemas, pode verificar se obtemos os mesmos resultados a cada etapa. Se quiser assistir ao vídeo, <a href="https://youtu.be/bUSXeQ4H20g">clique aqui</a> (vídeo em inglês).</p><h3 id="1-instale-as-ferramentas-de-cli-da-aws">1. Instale as ferramentas de CLI da AWS</h3><p>Antes de começarmos, você precisará instalar as ferramentas de CLI da AWS para poder digitar comandos em sua nuvem. A AWS oferece assistentes de instalação para todos os sistemas operacionais, então vou pular essa seção. Após uma instalação bem-sucedida, você precisará fazer login digitando o seguinte comando:</p><pre><code class="language-bash">$ aws configure
AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name [None]: us-east-2
Default output format [None]: json</code></pre><p>Para gerar chaves de acesso, você precisa fazer login no Console da AWS. Lá, clique em seu nome de usuário e selecione <em>My Security Credentials</em> (em português, "Minhas Credenciais de Segurança").</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/Screenshot-2021-03-16-at-22.27.53-1.png" class="kg-image" alt="Screenshot-2021-03-16-at-22.27.53-1" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/04/Screenshot-2021-03-16-at-22.27.53-1.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/04/Screenshot-2021-03-16-at-22.27.53-1.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/04/Screenshot-2021-03-16-at-22.27.53-1.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/04/Screenshot-2021-03-16-at-22.27.53-1.png 2000w" sizes="(min-width: 1200px) 1200px" width="2000" height="1401" loading="lazy"></figure><h3 id="2-crie-um-elastic-container-registry-ecr-">2. Crie um <em>Elastic Container Registry</em> (ECR)<br></h3><p>Assim que as ferramentas da CLI estiverem configuradas, precisaremos criar um espaço onde podemos armazenar os executáveis de nossa aplicação. Usamos o Docker, então nossos executáveis serão imagens do Docker que serão executadas em máquinas virtuais.<br>A AWS oferece um serviço dedicado para armazenar imagens chamado <em>Elastic Container Registry</em>. O comando a seguir criará um para nós:</p><pre><code class="language-bash">aws ecr create-repository --repository-name react-to-aws --region us-east-2</code></pre><p>Aqui estão os parâmetros:</p><ul><li><code>ecr</code> – acrônimo para "Elastic Container Registry".</li><li><code>repository-name</code> – o nome do nosso registro. Observe que utilizaremos esse nome posteriormente.</li><li><code>region</code> – código da região. Você pode encontrar a região mais próxima da sua para reduzir a laência da comunicação. <a href="https://docs.aws.amazon.com/general/latest/gr/rande.html">Aqui há uma lista de todas as regiões</a>. </li></ul><p>Para mais detalhes, consulte a documentação.</p><p>Aqui está a saída do console:</p><pre><code class="language-none">{
    "repository": {
        "repositoryArn": "arn:aws:ecr:us-east-2:1234567890:repository/react-to-aws2",
        "registryId": "1234567890",
        "repositoryName": "react-to-aws",
        "repositoryUri": "1234567890.dkr.ecr.us-east-2.amazonaws.com/react-to-aws2",
        "createdAt": "2021-03-16T22:50:23+04:00",
        "imageTagMutability": "MUTABLE",
        "imageScanningConfiguration": {
            "scanOnPush": false
        },
        "encryptionConfiguration": {
            "encryptionType": "AES256"
        }
    }
}</code></pre><h3 id="3-envie-as-imagens-do-docker-para-a-nuvem">3. Envie as imagens do Docker para a nuvem</h3><p>Nesta etapa, vamos enviar nossas imagens do Docker para a nuvem. Podemos fazer isso copiando os comandos de envio de nosso Console AWS.<br>Vamos abrir o Console AWS no navegador e clicar em Elastic Container Registry na lista <em><em>All Services - Containers</em> </em>(Todos os Serviços - Contêineres). Se você não alterou sua região, pode simplesmente <a href="https://us-east-2.console.aws.amazon.com/ecr/repositories?region=us-east-2">clicar aqui</a>. Você verá a lista completa de seus repositórios:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/Screenshot-2021-03-16-at-23.00.24-1.png" class="kg-image" alt="Screenshot-2021-03-16-at-23.00.24-1" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/04/Screenshot-2021-03-16-at-23.00.24-1.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/04/Screenshot-2021-03-16-at-23.00.24-1.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/04/Screenshot-2021-03-16-at-23.00.24-1.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/04/Screenshot-2021-03-16-at-23.00.24-1.png 2000w" sizes="(min-width: 1200px) 1200px" width="2000" height="1281" loading="lazy"></figure><p>Agoram você precisa selecionar o repositório <code>react-to-aws</code> e, em seguida, clicar em <em><em>View push commands</em></em> ("Visualizar comandos de envio") no menu (marcado com círculos vermelhos na imagem acima). Você verá a seguinte janela:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/Screenshot-2021-03-16-at-23.08.49.png" class="kg-image" alt="Screenshot-2021-03-16-at-23.08.49" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/04/Screenshot-2021-03-16-at-23.08.49.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/04/Screenshot-2021-03-16-at-23.08.49.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/04/Screenshot-2021-03-16-at-23.08.49.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/04/Screenshot-2021-03-16-at-23.08.49.png 2000w" sizes="(min-width: 1200px) 1200px" width="2000" height="1290" loading="lazy"></figure><p>Você precisa copiar todos comandos do modal no terminal. <strong>Não copie diretamente da caixa abaixo, pois não funcionarão:</strong></p><pre><code class="language-bash">$ aws ecr get-login-password --region us-east-2 | docker login --username AWS --password-stdin 123456789.dkr.ecr.us-east-2.amazonaws.com
Login Succeeded

$ docker build -t react-to-aws .
[+] Building 0.6s (8/8) FINISHED
...

$ docker tag react-to-aws:latest 123465789.dkr.ecr.us-east-2.amazonaws.com/react-to-aws:latest

$ docker push 123456789.dkr.ecr.us-east-2.amazonaws.com/react-to-aws:latest
The push refers to repository [123456789.dkr.ecr.us-east-2.amazonaws.com/react-to-aws:latest]
...
latest: digest: sha256:3921262a91fd85d2fccab1d7dbe7adcff84f405a3dd9c0e510a20d744e6c3f74 size: 1988</code></pre><p>Agora, feche o modal e clique no nome do repositório (<code>react-to-aws</code>) para listar as imagens disponíveis. Você deve ver essa tela:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/Screenshot-2021-03-16-at-23.17.56-1.png" class="kg-image" alt="Screenshot-2021-03-16-at-23.17.56-1" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/04/Screenshot-2021-03-16-at-23.17.56-1.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/04/Screenshot-2021-03-16-at-23.17.56-1.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/04/Screenshot-2021-03-16-at-23.17.56-1.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/04/Screenshot-2021-03-16-at-23.17.56-1.png 2000w" sizes="(min-width: 1200px) 1200px" width="2000" height="1290" loading="lazy"></figure><p>Sua aplicação está no repositório, pronta para implementação! Agora, clique em <em>Copy URI </em>(Copiar URI) <strong>e mantenha isso na sua 'área de transferência' (<em>clipboard</em>), ou copie em um arquivo de texto</strong>, pois precisaremos digitá-lo mais tarde!</p><h3 id="4-configurar-a-aplica-o">4. Configurar a aplicação</h3><p>Nossa imagem está disponível na nuvem. Agora, precisamos configurá-la.<br>Para executarmos máquinas virtuais, devemos definir algumas instruções, como portas abertas, variáveis de ambiente e assim por diante. A AWS chama isso de definição de tarefa (<em>task definition</em>).<br>Abra o console da AWS e clique em Elastic Container Service (ECS) na lista <em>All Services - Containers</em> ("Todos os Serviços - Contêineres"). Se você não alterou sua região, <a href="https://us-east-2.console.aws.amazon.com/ecs/home?region=us-east-2#/clusters">pode clicar aqui</a>.<br>Agora selecione <em>Task Definitions</em> ("Definições de Tarefas") e clique em <em>Create New Task Definition</em> ("Criar Definição de Tarefa"), conforme imagem abaixo:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/Screenshot-2021-03-17-at-00.07.54-1.png" class="kg-image" alt="Screenshot-2021-03-17-at-00.07.54-1" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/04/Screenshot-2021-03-17-at-00.07.54-1.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/04/Screenshot-2021-03-17-at-00.07.54-1.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/04/Screenshot-2021-03-17-at-00.07.54-1.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/04/Screenshot-2021-03-17-at-00.07.54-1.png 2000w" sizes="(min-width: 1200px) 1200px" width="2000" height="1290" loading="lazy"></figure><p>Temos duas opções para executar as tarefas: <code>FARGATE</code> e <code>EC2</code>. Escolha <code>FARGATE</code><em> </em>e avance para o próximo passo.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/Screenshot-2021-03-17-at-00.09.53.png" class="kg-image" alt="Screenshot-2021-03-17-at-00.09.53" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/04/Screenshot-2021-03-17-at-00.09.53.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/04/Screenshot-2021-03-17-at-00.09.53.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/04/Screenshot-2021-03-17-at-00.09.53.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/04/Screenshot-2021-03-17-at-00.09.53.png 2000w" sizes="(min-width: 1200px) 1200px" width="2000" height="1290" loading="lazy"></figure><p>No próximo passo, você precisa preencher o formulário com os seguintes valores:</p><ul><li><strong>Nomeclatura (Task Definition Name) </strong>– <code>react-to-aws-task</code>.</li><li><strong>Papel/Nível (Task Role)</strong> – <code>none</code>.</li><li><strong>Memória (Task memory) em GB </strong>– <code>0.5GB</code> (a menor).</li><li><strong>Recurso Processamento (Task CPU) em vCPU</strong> – <code>0.25 vCPU</code> (a menor).</li></ul><p>Assim que você chegar em <em>Container Definitions (</em>"Definições de container")<em>, </em>clique em <em>Add container</em><em> (</em>"Adicionar container"<em>)</em>:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/Screenshot-2021-03-17-at-00.18.19.png" class="kg-image" alt="Screenshot-2021-03-17-at-00.18.19" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/04/Screenshot-2021-03-17-at-00.18.19.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/04/Screenshot-2021-03-17-at-00.18.19.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/04/Screenshot-2021-03-17-at-00.18.19.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/04/Screenshot-2021-03-17-at-00.18.19.png 2000w" sizes="(min-width: 1200px) 1200px" width="2000" height="1288" loading="lazy"></figure><p>Preencha o formulário com os seguintes valores:</p><ul><li><strong>Nome do container (<em>Container Name</em>) </strong>– <code>react-to-aws</code>.</li><li><strong>Imagem (<em>Image</em>)</strong> – o URI do passo anterior. Você colou os dados em um bloco de notas, lembra?</li><li><strong>Limite de memória (<em>Memory Limits</em>) em MiB </strong>– <code>Soft limit</code> <code>128</code>.</li><li><strong>Mapeamento de portas (<em>Port mappings</em>)</strong> – <code>80</code> – a porta HTTP.</li></ul><p>Outras opções não são relevantes para nós. Agora, clique no botão <em>Add</em> ("Adicionar") para adicionar um contêiner e finalize a definição de tarefa clicando em <em>Create </em>("Criar"). Você deve ver a seguinte tela e clicar em <em>View Task Definition </em>("Visualizar definição de tarefa").</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/Screenshot-2021-03-17-at-00.24.56.png" class="kg-image" alt="Screenshot-2021-03-17-at-00.24.56" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/04/Screenshot-2021-03-17-at-00.24.56.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/04/Screenshot-2021-03-17-at-00.24.56.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/04/Screenshot-2021-03-17-at-00.24.56.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/04/Screenshot-2021-03-17-at-00.24.56.png 2000w" sizes="(min-width: 1200px) 1200px" width="2000" height="1288" loading="lazy"></figure><h3 id="5-vamos-executar-">5. Vamos executar!</h3><p>Agora podemos criar o <em>cluster </em>para executar nossa aplicação na nuvem. Você pode selecionar <em>Clusters</em> a partir do menu ao lado esquerdo e clicar em <em>Create Cluster</em> ("Criar Cluster"), conforme a imagem abaixo:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/Screenshot-2021-03-17-at-00.29.46.png" class="kg-image" alt="Screenshot-2021-03-17-at-00.29.46" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/04/Screenshot-2021-03-17-at-00.29.46.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/04/Screenshot-2021-03-17-at-00.29.46.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/04/Screenshot-2021-03-17-at-00.29.46.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/04/Screenshot-2021-03-17-at-00.29.46.png 2000w" sizes="(min-width: 1200px) 1200px" width="2000" height="1288" loading="lazy"></figure><p>Agora, temos três opções: <code>Networking only</code>, <code>EC2 Linux + Networking</code> e <code>EC2 Windows + Networking</code>. Selecione a primeira, <code>Networking only</code> ("Rede apenas") e avance para o próximo passo, onde você deve ver a seguinte tela:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/Screenshot-2021-03-17-at-00.34.35.png" class="kg-image" alt="Screenshot-2021-03-17-at-00.34.35" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/04/Screenshot-2021-03-17-at-00.34.35.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/04/Screenshot-2021-03-17-at-00.34.35.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/04/Screenshot-2021-03-17-at-00.34.35.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/04/Screenshot-2021-03-17-at-00.34.35.png 2000w" sizes="(min-width: 1200px) 1200px" width="2000" height="1288" loading="lazy"></figure><p>Digite <code>react-to-aws</code> como nome do <em>cluster</em> e crie no botão <em>Create</em>. Você deve ver uma mensagem indicando sucesso. Pode parecer similar à imagem abaixo (quando criamos a nossa tarefa). Agora, clique em <em>View Cluster </em>("Ver cluster").</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/Screenshot-2021-03-17-at-00.39.42-1.png" class="kg-image" alt="Screenshot-2021-03-17-at-00.39.42-1" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/04/Screenshot-2021-03-17-at-00.39.42-1.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/04/Screenshot-2021-03-17-at-00.39.42-1.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/04/Screenshot-2021-03-17-at-00.39.42-1.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/04/Screenshot-2021-03-17-at-00.39.42-1.png 2000w" sizes="(min-width: 1200px) 1200px" width="2000" height="1288" loading="lazy"></figure><p>Agora, clique na aba <em>Tasks</em> ("Tarefas") e clique em <em>Run new Task</em> ("Executar nova tarefa"). Parabéns! Chegamos ao último formulário! 😀</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/Screenshot-2021-03-17-at-00.41.10.png" class="kg-image" alt="Screenshot-2021-03-17-at-00.41.10" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/04/Screenshot-2021-03-17-at-00.41.10.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/04/Screenshot-2021-03-17-at-00.41.10.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/04/Screenshot-2021-03-17-at-00.41.10.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/04/Screenshot-2021-03-17-at-00.41.10.png 2000w" sizes="(min-width: 1200px) 1200px" width="2000" height="1288" loading="lazy"></figure><p>Preencha seu último formulário com os seguintes valores:</p><ul><li><strong>Tipo de lançamento (Launch type) </strong>– <code>FARGATE</code>.</li><li><strong>Cluster VPC</strong> – a primeira opção.</li><li><strong>Subrede (Subnet)</strong> – a primeira opção.</li></ul><p><strong>Mantenha os demais valores com o padrão</strong> e clique no botão <em>Run task </em>("Executar tarefa"<em>).</em> Você deve ver essa tela:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/Screenshot-2021-03-17-at-00.46.45-1.png" class="kg-image" alt="Screenshot-2021-03-17-at-00.46.45-1" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/04/Screenshot-2021-03-17-at-00.46.45-1.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/04/Screenshot-2021-03-17-at-00.46.45-1.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/04/Screenshot-2021-03-17-at-00.46.45-1.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/04/Screenshot-2021-03-17-at-00.46.45-1.png 2000w" sizes="(min-width: 1200px) 1200px" width="2000" height="1288" loading="lazy"></figure><p>Precisaremos aguardar cerca de um minuto até que o "Último status" (<em>Last Status</em>) mude para "EXECUTANDO" (<em>RUNNING</em>). Lembre-se de que você precisa clicar no botão "Atualizar" (<em>Refresh</em>) para atualizar a lista. Assim que o status da tarefa estiver em execução, clique no nome da tarefa.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/Screenshot-2021-03-17-at-00.50.52.png" class="kg-image" alt="Screenshot-2021-03-17-at-00.50.52" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/04/Screenshot-2021-03-17-at-00.50.52.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/04/Screenshot-2021-03-17-at-00.50.52.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/04/Screenshot-2021-03-17-at-00.50.52.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/04/Screenshot-2021-03-17-at-00.50.52.png 2000w" sizes="(min-width: 1200px) 1200px" width="2000" height="1179" loading="lazy"></figure><p>Na seção "Rede" (<em>Network),</em> você pode encontrar o IP público (<em>Public IP)</em> do seu contêiner. Abra-o no navegador para visualizar sua aplicação.</p><h2 id="resumo">Resumo</h2><p>Se você está no início de sua carreira – talvez nunca tenha implementado uma aplicação por conta própria – mas é bom aprender essa habilidade, porque um dia precisará fazer isso.<br>Todo projeto precisa chegar aos usuários. Caso contrário, não terá chance de ser bem-sucedido e nunca será útil e/ou rentável.<br>O processo de configuração pode ser um pouco tedioso, mas a boa notícia é que você só precisa fazer isso uma vez! 🙂<br>Depois de configurar tudo, suas implantações futuras serão mais simples. Você só precisa enviar a nova imagem e reiniciar a tarefa para implantar uma nova versão de sua aplicação.<br>Se você estiver interessado em se aprofundar na AWS, o FreeCodeCamp oferece <a href="https://www.freecodecamp.org/news/aws-certified-cloud-practitioner-study-course-pass-the-exam-with-this-free-13-hour-course/">um tutorial gratuito sobre o assunto</a> (cerca de 14 horas).<br>Você pode encontrar <strong>uma gravação em vídeo deste tutorial (17 minutos)</strong> em meu canal no YouTube. Estou no início de minha jornada no YouTube – pelo menos semanalmente, faço upload de um vídeo sobre programação. Significaria muito para mim se você assistisse à minha gravação em vídeo, se inscrevesse no canal e clicasse no botão de curtir.</p><figure class="kg-card kg-embed-card" data-test-label="fitted">
        <div class="fluid-width-video-container">
          <div style="padding-top: 56.49999999999999%;" class="fluid-width-video-wrapper">
            <iframe width="200" height="113" src="https://www.youtube.com/embed/bUSXeQ4H20g?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" title="How To Deploy React On AWS With Docker And NGINX" name="fitvid0"></iframe>
          </div>
        </div>
      </figure><p><strong>Você pode encontrar todo o código neste repositório do GitHub</strong>: <a href="https://github.com/mateuszsokola/react-to-aws">https://github.com/mateuszsokola/react-to-aws</a></p><p>Você pode enviar mensagens diretas ao autor (em inglês) pelo Twitter: <a href="https://twitter.com/msokola">@msokola</a></p><p>Pode enviar mensagens diretas ao tradutor (em português ou inglês) pelo Twitter: <a href="https://twitter.com/drcrescencio">@drcrescencio</a></p><p>É isso, pessoal! Tenham um bom dia! 🙂</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/vidar-nordli-mathisen-xgP0GNl9Gzg-unsplash.jpg" class="kg-image" alt="vidar-nordli-mathisen-xgP0GNl9Gzg-unsplash" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/04/vidar-nordli-mathisen-xgP0GNl9Gzg-unsplash.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/04/vidar-nordli-mathisen-xgP0GNl9Gzg-unsplash.jpg 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/04/vidar-nordli-mathisen-xgP0GNl9Gzg-unsplash.jpg 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/04/vidar-nordli-mathisen-xgP0GNl9Gzg-unsplash.jpg 2000w" sizes="(min-width: 720px) 720px" width="2000" height="1238" loading="lazy"><figcaption>Foto: <a href="https://unsplash.com/@vidarnm?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Vidar Nordli-Mathisen</a>, extraída do <a href="https://www.freecodecamp.org/news/s/photos/ship-storm?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Por que você deve usar o React.js para o desenvolvimento para a web ]]>
                </title>
                <description>
                    <![CDATA[ Se você é novo no React.js, você pode estar se perguntando o porquê de ele ser tão popular e por que você deveria usá-lo em suas aplicações. Se esse for o caso, você está no lugar certo. Vamos discutir o que torna o React.js tão bom e porque você deve ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/por-que-voce-deve-usar-o-react-js-para-o-desenvolvimento-para-a-web/</link>
                <guid isPermaLink="false">6509bbaaade67a03f81e53a8</guid>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Luiz Nison Filler ]]>
                </dc:creator>
                <pubDate>Mon, 08 Apr 2024 10:36:36 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2024/03/image-7.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/why-use-react-for-web-development/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Why You Should Use React.js For Web Development</a>
      </p><p>Se você é novo no React.js, você pode estar se perguntando o porquê de ele ser tão popular e por que você deveria usá-lo em suas aplicações. Se esse for o caso, você está no lugar certo.</p><p>Vamos discutir o que torna o React.js tão bom e porque você deve usá-lo em seus projetos.</p><h1 id="-ndice"><strong>Índice</strong></h1><ul><li>Breve história do React.js</li><li>Por que você deveria usar o React?</li><li>O React é flexível</li><li>O React possui uma ótima experiência de desenvolvedor</li><li>O React tem suporte/recursos do Facebook</li><li>O React também tem um amplo suporte da comunidade</li><li>O React possui um ótimo desempenho</li><li>O React é fácil de testar</li></ul><h2 id="breve-hist-ria-do-react-js"><strong>Breve história do Rea<strong>ct.js</strong></strong></h2><p>O Facebook criou o <a href="https://reactjs.org/">React.js</a> em 2011 para o seu próprio uso. Como você sabe, Facebook é, atualmente, um dos maiores sites de redes sociais da web do mundo.</p><p>Em 2012, o Instagram, que é uma subsidiária do Facebook, também começou a utilizá-lo.</p><p>Em 2013, o Facebook disponibilizou o código do React.js como código-aberto. Inicialmente, a comunidade de desenvolvedores o rejeitou, pois fazia uso de Markup e JavaScript em um único arquivo. No entanto, à medida que mais pessoas experimentavam, elas começaram a apoiar a abordagem centrada em componentes para separação de responsabilidades.</p><p>Em 2014, diversas empresas grandes começaram a usar o React.js em seus ambientes de produção.</p><p>Em 2015, o Facebook também disponibilizou o código do <a href="https://reactnative.dev/">React Native</a> como código-aberto. O React Native é uma biblioteca que nos permite a criação de aplicativos nativos para dispositivos móveis em Android e iOS usando o React.js.</p><p>Em 2016, com a versão 15, o React.js começou a empregar o versionamento semântico. Isso também ajudou a transmitir à comunidade de desenvolvedores que o React estava mais estável.</p><p>Hoje, o React.js é usado por muitas empresas dentre as <strong><strong><a href="https://fortune.com/ranking/fortune500/">Fortune 500</a></strong>. </strong>O Facebook possui uma equipe de desenvolvedores em tempo integral dedicada ao React. Eles, regularmente, lançam correções de bugs, melhorias, postagens em blogs e documentação.</p><h2 id="por-que-voc-deveria-usar-o-react"><strong>Por que você deveria usar o React<strong>?</strong></strong></h2><p>Você pode estar se perguntando por que você deveria usar o React.js. Afinal, com o aumento dos usos do JavaScript nos últimos anos, sabemos que há uma variedade de opções disponíveis no mercado, tais como <a href="https://angular.io/">Angular </a>e <a href="https://vuejs.org/">Vue.js</a>. Então, por que React?</p><p>Vamos explorar os seis motivos principais para usar o React.js.</p><h2 id="o-react-flex-vel"><strong>O <strong>React </strong>é f<strong>lex</strong>ível</strong></h2><p>O React é consideravelmente flexível. Após aprendê-lo, você pode usá-lo numa variedade de plataformas para construir interfaces de usuário de qualidade. O React é uma biblioteca, NÃO um<em> framework</em>. Sua abordagem de biblioteca o possibilitou evoluir e se tornar uma ferramenta notável.</p><p>O React foi criado com um único foco: criar componentes para aplicações para a web. Um <a href="https://www.freecodecamp.org/news/how-to-write-better-react-components/">componente do React</a> (texto em inglês) pode ser qualquer coisa em sua aplicação para a web como, por exemplo, um botão, um texto, um <em>label</em> ou um <em>grid</em>.</p><p>Porém, à proporção que a popularidade do React cresceu, seu ecossistema também ampliou para abranger diversos casos de uso.</p><p>Você pode gerar um site estático com React usando ferramentas como, por exemplo, o <a href="https://www.gatsbyjs.com/">Gatsby</a>. Você pode usar o React Native para construir aplicações para dispositivos móveis. Você, igualmente, pode criar uma aplicação para desktop, usando uma ferramenta como o <a href="https://www.electronjs.org/">Electron</a>, que consegue ser executada em Mac e Windows com a tecnologia React.js.</p><p>O React, da mesma maneira, suporta à renderização no servidor de seus componentes usando ferramentas como o <a href="https://nextjs.org/">Next.js</a>. Você também pode usar o React.js para criar um site da web de realidade virtual e experiências em 360 graus usando o React VR.</p><blockquote>"Aprenda o React uma vez e escreva código em qualquer lugar" - Reactjs.org</blockquote><p>Você também pode usar o React em suas aplicações já existentes. O React foi projetado com isso em mente. Você pode mudar uma pequena parte da sua aplicação existente usando o React e, se essa alteração funcionar, você pode começar a converter sua aplicação inteira para o React.js. O Facebook aplicou a mesma abordagem.</p><blockquote>"A principal vantagem de se usar uma biblioteca em vez de um <em>framework</em> é o fato de que as bibliotecas são leves. Há uma liberdade para escolher ferramentas diversas. O <em>framework</em>, por outro lado, consiste em um ecossistema completo para se criar uma aplicação. Não existe um <em>modo fácil<em> </em></em>de se usar outras ferramentas que não sejam do <em>framework</em>."</blockquote><h2 id="o-react-possui-uma-tima-experi-ncia-de-desenvolvedor">O React possui uma ótima experiência de desenvolvedor</h2><p>Seu time se apaixonará pelo React quando eles começarem a programar com ele. O rápido desenvolvimento e a API enxuta do React combinados criam uma fantástica experiência de desenvolvimento.</p><p>A API do React é muito simples, pois possui poucos conceitos para aprender. Aqui está um curto exemplo de um componente do React:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/03/React-Component.png" class="kg-image" alt="React-Component" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/03/React-Component.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/03/React-Component.png 779w" sizes="(min-width: 720px) 720px" width="779" height="253" loading="lazy"><figcaption>Componente do React</figcaption></figure><p>Você precisa apenas importar a biblioteca do React. <strong><em>Message</em></strong> é um componente que recebe uma <em>props</em> (entrada) e retorna JSX.</p><p>JSX é uma sintaxe especial que se assemelha ao HTML, convertendo as chamadas da API do React e, ao final, renderizando HTML.</p><p><em>Frameworks</em> tradicionais, como o Angular e Vue, potencializam o HTML. Eles usam JavaScript dentro do HTML. Eles criaram atributos HTML que fornecem capacidades adicionais a ele.</p><p>O principal problema com essa abordagem é que você tem que aprender esses novos atributos do HTML ou sempre ficar consultando a documentação oficial.</p><p>Aqui está um exemplo de laço de repetição no Angular. Olhe o atributo <strong><strong>*ngFor</strong></strong>:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/03/Angular-Loops.png" class="kg-image" alt="Angular-Loops" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/03/Angular-Loops.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/03/Angular-Loops.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/03/Angular-Loops.png 1056w" sizes="(min-width: 720px) 720px" width="1056" height="196" loading="lazy"><figcaption>Exemplo de laço de repetição no Angular (Fonte: <a href="https://angular.io/">Angular</a>)</figcaption></figure><p>Aqui, por outro lado, temos um exemplo de laço de repetição no Vue.js. Dê uma olhada no atributo <strong><strong>v-for</strong></strong>:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/03/vue-looping.png" class="kg-image" alt="vue-looping" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/03/vue-looping.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/03/vue-looping.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/03/vue-looping.png 1062w" sizes="(min-width: 720px) 720px" width="1062" height="251" loading="lazy"><figcaption>Exemplo de laço de repetição no Vue (Fonte: <a href="https://vuejs.org/">vuejs.org</a>)</figcaption></figure><p>O React usa uma conduta oposta. Ele utiliza HTML (JSX) dentro do JavaScript. Eu gosto dessa abordagem porque, nela, você pode lidar com JavaScipt e HTML puros.</p><p>Aqui temos um exemplo de laço de repetição no React.js</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/03/loops-in-React.png" class="kg-image" alt="loops-in-React" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/03/loops-in-React.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/03/loops-in-React.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/03/loops-in-React.png 1179w" sizes="(min-width: 720px) 720px" width="1179" height="511" loading="lazy"><figcaption>Exemplo de laços de repetição no React (Fonte: <a href="https://reactjs.org/">Reactjs.org</a>)</figcaption></figure><p>‌O componente <strong><strong>NumberList </strong></strong>do React usa código em JavaScript puro (a função 'map'). Além disso, você pode observar que o JSX é uma simples, e bem conhecida, tag HTML com atributos elegantes. A função '<em>render</em>' está apenas renderizando o componente <em>NumberList</em> no elemento raiz no arquivo HTML.</p><p>O que mais você precisa, enquanto desenvolvedor, se tem à disposição uma plataforma onde você pode lidar com JavaScript e HTML puros e, ainda, criar uma Interface de Usuário interativa?</p><p><strong>Observação<strong>:</strong></strong> <em>quando eu digo "JavaScript puro", isso não significa que você usará simplesmente JavaScript no React. O React é uma biblioteca do JavaScript e ele possui sua camada baseada no próprio JavaScript. PORÉM, como eu disse, a API do React é bem enxuta e simples de aprender. Angular e Vue forçam suas regras a você. O React é mais conceitual. Ele mostra como você pode fazer um melhor uso do JavaScript no estilo do React.</em></p><p>O React.js também nos disponibiliza o pacote <a href="https://www.freecodecamp.org/news/how-to-build-a-react-project-with-create-react-app-in-10-steps/">create-react-app</a>, que permite a começar instantaneamente o desenvolvimento.</p><h2 id="o-react-tem-suporte-recursos-do-facebook">O React tem suporte/recursos do Facebook</h2><p>O React é amplamente usado na aplicação e no site da web do Facebook e no Instagram. É por isso que o Facebook é profundamente comprometido com isso. Eles usam mais de 50 mil componentes do React em seu ambiente de produção. Os quatro principais contribuidores do React no GitHub são funcionários em tempo integral do Facebook.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/03/React-js-Top-Contributors.jpg" class="kg-image" alt="React-js-Top-Contributors" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/03/React-js-Top-Contributors.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/03/React-js-Top-Contributors.jpg 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/03/React-js-Top-Contributors.jpg 1039w" sizes="(min-width: 720px) 720px" width="1039" height="642" loading="lazy"><figcaption>Maiores colaboradores do React.js</figcaption></figure><p>Além disso, o time do React mantém um <a href="https://reactjs.org/blog/all.html/">blog</a> que constantemente fornece detalhes de cada novo lançamento.</p><p>Por conta do sólido comprometimento do Facebook com o React em produção, quando ocorrem mudanças significativas (breaking changes) no React, o Facebook consistentemente provê um <a href="https://github.com/reactjs/react-codemod">Codemod</a> que automatiza a mudança. </p><p>O Codemod é uma ferramenta de linha de comando que automatiza mudanças em sua base de código. Quando uma nova especificação entra no React, o Codemod automaticamente substitui velhos componentes com a nova especificação.</p><p>Desde 2015, a popularidade do React tem crescido constantemente. Ele possui uma comunidade muito grande e bastante ativa. Seu <a href="https://github.com/facebook/react">repositório no GitHub</a> tem mais de 164 mil estrelas. É um dos cinco principais repositórios na plataforma.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/03/React-Git-Repository.png" class="kg-image" alt="React-Git-Repository" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/03/React-Git-Repository.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/03/React-Git-Repository.png 928w" width="928" height="434" loading="lazy"><figcaption>Repositório do React no GitHub</figcaption></figure><p>O <a href="https://www.npmjs.com/package/react">pacote do NPM</a> do React tem, também, milhões de downloads semanalmente.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/03/React-NPM-Package-Downlaods.png" class="kg-image" alt="React-NPM-Package-Downlaods" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/03/React-NPM-Package-Downlaods.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/03/React-NPM-Package-Downlaods.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/03/React-NPM-Package-Downlaods.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/03/React-NPM-Package-Downlaods.png 1799w" sizes="(min-width: 1200px) 1200px" width="1799" height="717" loading="lazy"></figure><p>Mais de 9 mil empresas relataram no <a href="https://stackshare.io/react">Stackshare</a> que estão usando React. Você até pode ver empresas da Fortune 500.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/03/Stackshare-React.png" class="kg-image" alt="Stackshare-React" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/03/Stackshare-React.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/03/Stackshare-React.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/03/Stackshare-React.png 1349w" sizes="(min-width: 1200px) 1200px" width="1349" height="485" loading="lazy"><figcaption>Empresas que usam o React</figcaption></figure><p>A <a href="https://www.reactiflux.com/">Reactiflux</a> é uma comunidade especialmente feita para desenvolvedores do React. Mais de 110 mil membros da comunidade estão engajados em ajudar a resolver e compartilhar problemas relativos ao React.</p><p>Um dos sites da web mais populares entre os desenvolvedores de software é o <a href="https://stackoverflow.com/">StackOverflow</a>. Você pode ver que há mais de 250 mil perguntas feitas sobre o React e bibliotecas relacionadas a ele.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/03/React-in-Stackoverflow.png" class="kg-image" alt="React-in-Stackoverflow" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/03/React-in-Stackoverflow.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/03/React-in-Stackoverflow.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/03/React-in-Stackoverflow.png 1202w" sizes="(min-width: 1200px) 1200px" width="1202" height="368" loading="lazy"><figcaption>React no StackOverflow</figcaption></figure><p>Em alguns casos, você nem precisa criar seus próprios componentes. Existem várias bibliotecas de componentes gratuitas e maduras disponíveis on-line.</p><p>Aqui estão alguns exemplos:</p><ul><li>A Microsoft criou a biblioteca de componente <a href="https://developer.microsoft.com/en-us/fluentui#/">Fluent UI</a>, que possibilita desenvolver sua interface de usuário (semelhante a do <a href="https://www.office.com/">office</a>).</li><li>A <a href="https://material-ui.com/">Material-UI</a> oferece componentes do React que implementam as diretrizes de interface de usuário do Google Material.</li><li>A <a href="https://react-bootstrap.github.io/">React-Bootstrap</a> contém componentes do React que facilitam o trabalho com o Bootstrap.</li><li>Ademais, confira a lista <a href="https://github.com/brillout/awesome-react-components">Awesome React Components</a> no GitHub para encontrar mais componentes do React.</li></ul><p>Também existem projetos/bibliotecas maduras relacionadas que você pode usar com React.</p><ul><li>Se você quiser roteamento, então pode empregar o <a href="https://reactrouter.com/">React Router</a>. Se você deseja gerenciar um sistema de dados mais complexo, então utilize o <a href="https://redux.js.org/">Redux</a> e o <a href="https://mobx.js.org/README.html">MobX</a><a href="https://redux.js.org/"></a><a href="https://mobx.js.org/README.html">.</a></li><li>Para testes automatizados, use <a href="https://jestjs.io/">Jest</a>, que também é desenvolvido pelo Facebook.</li><li>Para chamadas a APIs RESTful, use o <a href="https://graphql.org/">GraphQL</a>.</li><li>Para renderização do lado do servidor de componentes do React com Node, faça uso do <a href="https://expressjs.com/">Express.js</a>.</li></ul><p>Todas essas bibliotecas e ferramentas são importantes, pois se você está procurando criar algo no React, você encontrará na web ajuda e soluções em abundância para tudo o que precisar.</p><h2 id="react-possui-um-timo-desempenho">React possui um ótimo desempenho</h2><p>A equipe do React percebeu que o JavaScript é rápido, mas atualizar o DOM o torna lento. O React minimiza as mudanças no DOM, tendo descoberto uma mais eficiente e inteligente de atualizá-lo.</p><p>Antes do React, a maioria dos <em>frameworks</em> e bibliotecas atualizava o DOM de maneira não inteligente para refletir um novo estado, resultando em mudanças em uma parte significativa da página.</p><p>O React monitora os valores do estado de cada componente com o <a href="https://reactjs.org/docs/faq-internals.html">Virtual DOM</a>. Quando o estado do componente é alterado, o React compara o estado existente do DOM com o que o novo DOM deveria parecer. Depois disso, ele encontra a maneira menos custosa de atualizá-lo.</p><p>Isso não parece ser muito fácil, mas o React lida muito bem com isso nos bastidores. Ele possui múltiplos benefícios, tais como evitar o 'layout trashing', que ocorre quando o navegador tem de recalcular a posição de tudo quando o elemento do DOM é modificado.</p><p>Além disso, como a maioria das aplicações tem sido usada em dispositivos móveis, elas precisam ser altamente eficientes. Portanto, economizar bateria e poder de CPU é muito importante.</p><p>O modelo simples de programação do React permite que ele mude os estados automaticamente quando dados são atualizados. Isso ocorre na memória, o que torna o processo bastante rápido.</p><p>O tamanho da biblioteca do React também é enxuto. É de menos de <strong>6kb</strong> (menos de 3kb quando compactado em gzip). Isso é significativamente inferior ao tamanho dos seus concorrentes.</p><h2 id="o-react-f-cil-de-testar">O React é fácil de testar</h2><p>O design do React é muito amigável para testes.</p><ul><li>O teste de interfaces de usuário tradicionais pode ser complicado de configurar. Por outro lado, você requer bem pouca ou nenhuma configuração para testar no React.</li><li>Testar interfaces de usuário tradicionais requer navegadores para os testes, mas você pode testar componentes do React rápida e facilmente usando a linha de comando no Node.</li><li>Os testes tradicionais de interface de usuário no navegador são lentos. No entanto, os testes de linha de comando são rápidos e você pode executar uma quantidade considerável de conjuntos de testes ao mesmo tempo.</li><li>O teste tradicional de interface de usuário no navegador, frequentemente, consome tempo e é desafiador para manter. Os testes em React podem ser escritos rapidamente usando ferramentas como Jest e <a href="https://enzymejs.github.io/enzyme/">Enzyme</a>.</li></ul><p>Há uma vasta variedade de <em>frameworks</em> JavaScript de testes disponíveis na web, os quais você pode implementar para testar o React.js (uma vez que também é uma biblioteca JavaScript). Alguns dos <em>frameworks</em> populares são o <a href="https://mochajs.org/">Mocha</a>, o <a href="https://jasmine.github.io/">Jasmine</a>, o <a href="https://github.com/substack/tape">Tape</a>, o <a href="https://qunitjs.com/">QUnit</a> e o <a href="https://github.com/avajs/ava">AVA</a>.</p><h2 id="conclus-o">Conclusão</h2><p>O React é uma ferramenta excelente para criar aplicações interativas para dispositivos móveis, para a web e para outras plataformas.</p><p>Tanto a popularidade quanto a utilização do React estão aumentando dia a dia por uma boa razão. Como desenvolvedor, programar em React torna você melhor em JavaScript, uma linguagem que detém, atualmente, aproximadamente 90% do mercado de desenvolvimento para a web.</p><p><em>Muito obrigado por ler este artigo. Conecte-se com o autor pelo <a href="https://www.linkedin.com/in/suraj-surve/">LinkedIn</a>.</em></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ React para principiantes – um guia do React.js para programadores de front-end ]]>
                </title>
                <description>
                    <![CDATA[ > Tradução em português europeu O React é um dos frameworks mais populares do JavaScript alguma vez criados, e acredito que seja uma das melhores ferramentas que anda por aí. O objetivo deste manual é fornecer um guia inicial para aprender React. > Nota da tradução: grande parte dos conceitos ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/react-para-principiantes-um-guia-do-react-js-para-programadores-de-front-end/</link>
                <guid isPermaLink="false">64b0062db04bf0067ce23b17</guid>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Afonso Branco ]]>
                </dc:creator>
                <pubDate>Wed, 29 Nov 2023 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/11/book-2.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/react-beginner-handbook/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">React for Beginners – A React.js Handbook for Front End Developers</a>
      </p><blockquote>Tradução em português europeu</blockquote><p>O React é um dos <em>frameworks </em>mais populares do JavaScript alguma vez criados, e acredito que seja uma das melhores ferramentas que anda por aí.</p><p>O objetivo deste manual é fornecer um guia inicial para aprender React.</p><blockquote>Nota da tradução: grande parte dos conceitos trabalhados neste manual seguem válidos para todas as versões de React. No entanto, é importante reforçar que, desde a concepção do artigo original, o React passou por atualizações e é possível que algumas das soluções oferecidas aqui estejam diferentes em versões mais recentes.</blockquote><p>No final deste manual, terás conhecimentos básicos sobre:</p><ul><li>O que é o React e porque é tão popular</li><li>Como instalar o React</li><li>Componentes do React</li><li><em>State</em> do React</li><li><em>Props</em> do React</li><li>Manipulação de eventos de utilizador em React</li><li>Eventos de ciclo de vida num componente do React</li></ul><p>Estes tópicos serão a base sobre a qual construirás em outros tutoriais de React mais avançados.</p><p>Este manual é escrito especialmente para programadores de JavaScript que estão a começar com o React. Por isso, vamos começar.</p><h2 id="o-que-react"><strong>O que é React?</strong></h2><p>O React é uma biblioteca do JavaScript que tem o objetivo de simplificar o desenvolvimento de interfaces visuais.</p><p>Desenvolvido pela Facebook e lançado ao mundo em 2013, ele impulsiona algumas das aplicações mais utilizadas no mundo, potenciando o Facebook e o Instagram, entre outras inúmeras aplicações.</p><p>O seu objetivo principal é facilitar o raciocínio sobre uma interface e o seu estado (em inglês, <em>state</em>), a qualquer momento. O React faz isso ao dividir a UI (Interface de Utilizador, em português) numa coleção de componentes.</p><p>Podes enfrentar algumas dificuldades iniciais ao aprender React. Porém, assim que fizer o "clique", garanto-te que será uma das melhores experiências que terás. O React facilita muitas coisas e o seu ecossistema está repleto de óptimas bibliotecas e ferramentas.</p><p>O React por si só tem uma API muito pequena e, basicamente, precisas compreender quatro conceitos para começar:</p><ul><li>Componentes</li><li>JSX</li><li><em>State</em></li><li><em>Props</em></li></ul><p>Vamos explorar todos eles neste manual e vamos deixar os conceitos mais avançados para outros tutoriais. Irei fornecer algumas dicas na última secção sobre como seguir em frente.</p><p>Podes também fazer o <a href="https://flaviocopes.com/page/react-handbook/">download deste manual em PDF / ePub / formato Mobi gratuitamente</a>.</p><h2 id="resumo-do-manual"><strong>Resumo do manual</strong></h2><ul><li><a href="https://www.freecodecamp.org/portuguese/news/#quanto-javascript-precisas-saber-para-utilizar-o-react">Quanto JavaScript precisas saber para utilizar o React</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/react-para-principiantes-um-guia-do-react-js-para-programadores-de-front-end/#porque-deves-aprender-react">Porque deves aprender React?</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/react-para-principiantes-um-guia-do-react-js-para-programadores-de-front-end/#como-instalar-o-react">Como instalar o React</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/react-para-principiantes-um-guia-do-react-js-para-programadores-de-front-end/#componentes-do-react">Componentes do React</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/react-para-principiantes-um-guia-do-react-js-para-programadores-de-front-end/#introdu-o-ao-jsx">Introdução ao JSX</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/react-para-principiantes-um-guia-do-react-js-para-programadores-de-front-end/#utilizar-jsx-para-compor-uma-ui">Utilizar JSX para compor uma UI</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/react-para-principiantes-um-guia-do-react-js-para-programadores-de-front-end/#a-diferen-a-entre-jsx-e-html">A diferença entre JSX e HTML</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/react-para-principiantes-um-guia-do-react-js-para-programadores-de-front-end/#incorporar-javascript-em-jsx">Incorporar JavaScript em JSX</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/react-para-principiantes-um-guia-do-react-js-para-programadores-de-front-end/#gerir-o-state-em-react">Gerir o state em React</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/react-para-principiantes-um-guia-do-react-js-para-programadores-de-front-end/#props-de-componente-em-react">Props de componente em React</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/react-para-principiantes-um-guia-do-react-js-para-programadores-de-front-end/#fluxo-de-dados-numa-aplica-o-em-react">Fluxo de dados numa aplicação em React</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/react-para-principiantes-um-guia-do-react-js-para-programadores-de-front-end/#lidar-com-eventos-de-utilizador-em-react">Lidar com eventos de utilizador em React</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/react-para-principiantes-um-guia-do-react-js-para-programadores-de-front-end/#eventos-de-ciclo-de-vida-num-componente-react">Eventos de ciclo de vida num componente React</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/react-para-principiantes-um-guia-do-react-js-para-programadores-de-front-end/#para-onde-seguir-a-partir-daqui">Para onde seguir a partir daqui</a></li></ul><h2 id="quanto-javascript-precisas-saber-para-utilizar-o-react"><strong>Quanto JavaScript precisas saber para utilizar o React</strong></h2><p>Antes de avançar diretamente para o React, deves ter uma boa compreensão de alguns conceitos fundamentais do JavaScript.</p><p>Não precisas ser um especialista em JavaScript, mas acho que precisas de uma compreensão (textos do autor abaixo em inglês) de:</p><ul><li><a href="https://flaviocopes.com/javascript-variables/">Variáveis</a></li><li><a href="https://flaviocopes.com/javascript-arrow-functions/">Funções de seta</a></li><li><a href="https://flaviocopes.com/javascript-rest-spread/">Trabalhar com objetos e arrays utilizando Rest e Spread</a></li><li><a href="https://flaviocopes.com/javascript-destructuring/">Desestruturação de objetos e arrays</a></li><li><a href="https://flaviocopes.com/javascript-template-literals/">Literais de template</a></li><li><a href="https://flaviocopes.com/javascript-callbacks/">Funções de callback</a></li><li><a href="https://flaviocopes.com/es-modules/">Módulos da ES</a></li></ul><p>Se estes conceitos não te forem familiares, deixei alguns links para descobrires mais sobre esses assuntos.</p><h2 id="porque-deves-aprender-react"><strong>Porque deves aprender React?</strong></h2><p>Recomendo vivamente que qualquer programador para a Web tenha, pelo menos, uma compreensão básica do React.</p><p>Recomendo isto por algumas razões.</p><ol><li>O React é muito popular. Como programador, é bem provável que vás trabalhar num projeto com React no futuro. Talvez num projeto existente, ou talvez a tua equipa vai querer que trabalhes numa nova aplicação com base no React.</li><li>Hoje em dia, muitas das ferramentas são criadas utilizando o React no seu núcleo. Frameworks populares e ferramentas como Next.js, Gatsby e muitos outros utilizam React em segundo plano.</li><li>Como engenheiro de front-end, o React provavelmente surgirá numa entrevista de emprego.</li></ol><p>Estas são todas boas razões, mas uma das principais razões para eu querer que aprendas React é que o React é espetacular.</p><p>O React promove várias boas práticas de desenvolvimento, incluindo a capacidade de reutilizar o código e desenvolvimento orientado a componentes. É rápido, é leve, e a maneira como te faz pensar sobre o fluxo de dados na aplicação combina com vários cenários comuns.</p><h2 id="como-instalar-o-react"><strong>Como instalar o React</strong></h2><p>Existem algumas formas diferentes de instalar o React.</p><p>Para começar, recomendo vivamente uma abordagem, que é utilizar a ferramenta oficial recomendada, chamada <code>create-react-app</code>.</p><p><code>create-react-app</code> é uma aplicação de linha de comandos, que tem o objetivo de te colocar a par do React sem demoras.</p><p>Começas por utilizar o <code>npx</code>, que é uma forma fácil de descarregar e executar comandos do Node.js sem ter de instalá-los.</p><blockquote><em>Vê o meu guia sobre o<em> npx </em>aqui<em>: </em></em><a href="https://flaviocopes.com/npx/"><em><em>https://flaviocopes.com/npx/</em></em></a><em> (em inglês)</em></blockquote><p>O <code>npx</code> vem com o <code>npm</code> (desde a versão 5.2). Se ainda não tiveres nenhum npm instalado, instala agora a partir de <a href="https://nodejs.org/">https://nodejs.org</a> (o npm é instalado com o Node).</p><p>Se não tiveres a certeza que versão tens do npm, executa <code>npm -v</code> para verificar se precisas de atualizar.</p><blockquote><em>Dica<em>: </em>analisa o meu tutorial sobre o terminal<em> OSX</em>, disponível em<em> <a href="https://flaviocopes.com/macos-terminal/">https://flaviocopes.com/macos-terminal/</a></em> (em inglês),<em> </em>caso ainda não te sintas à vontade a utilizar o<em> terminal. </em>Aplica-se<em> </em>ao<em> Mac </em>e ao<em> Linux.</em></em></blockquote><p>Quando executas <code>npx create-react-app &lt;app-name&gt;</code>, o <code>npx</code> <em>irá descarregar</em> a versão mais recente de <code>create-react-app</code>. Executa-a, e de seguida, remove-a do teu sistema.</p><p>Isto é ótimo porque nunca vais ter uma versão desatualizada no teu sistema, e sempre que a executares, iras obter a versão mais recente e o melhor código disponível.</p><p>Vamos então começar:</p><pre><code class="language-sh">npx create-react-app todolist
</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/11/cra-start.png" class="kg-image" alt="cra-start" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/11/cra-start.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/11/cra-start.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2023/11/cra-start.png 1200w" sizes="(min-width: 720px) 720px" width="1200" height="789" loading="lazy"></figure><p>Isto é quando termina a execução:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/11/create-react-app-finished.png" class="kg-image" alt="create-react-app-finished" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/11/create-react-app-finished.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/11/create-react-app-finished.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2023/11/create-react-app-finished.png 1200w" sizes="(min-width: 720px) 720px" width="1200" height="789" loading="lazy"></figure><p><code>create-react-app</code> criou uma estrutura de ficheiros na pasta que indicaste (<code>todolist</code>, neste caso), e inicializou um repositório <a href="https://flaviocopes.com/git/">Git</a>.</p><p>Também adicionou alguns comandos no ficheiro <code>package.json</code>:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/11/0038f8fe-17b1-40af-b4e8-3b47710ea294.png" class="kg-image" alt="0038f8fe-17b1-40af-b4e8-3b47710ea294" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/11/0038f8fe-17b1-40af-b4e8-3b47710ea294.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/11/0038f8fe-17b1-40af-b4e8-3b47710ea294.png 925w" sizes="(min-width: 720px) 720px" width="925" height="1039" loading="lazy"></figure><blockquote>Nota da tradução: como é possível ver na parte das dependências, a versão na época da criação deste artigo é a versão 16.14.0. A versão atual, no momento em que esta tradução foi realizada, é a 18.2.0.</blockquote><p>Então, podes iniciar imediatamente a aplicação ao seguir para a pasta da aplicação recentemente criada e executando <code>npm start</code>.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/11/cra-running.png" class="kg-image" alt="cra-running" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/11/cra-running.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/11/cra-running.png 925w" sizes="(min-width: 720px) 720px" width="925" height="539" loading="lazy"></figure><p>De início, este comando executa a aplicação na tua porta local 3000, e abre o teu navegador, apresentando o ecrã de boas vindas:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/11/cra-browser.png" class="kg-image" alt="cra-browser" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/11/cra-browser.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/11/cra-browser.png 940w" sizes="(min-width: 720px) 720px" width="940" height="985" loading="lazy"></figure><p>Agora, está tudo pronto para trabalhares na aplicação!</p><h2 id="componentes-do-react"><strong>Componentes do React</strong></h2><p>Na última secção, viste como criar a tua primeira aplicação de React.</p><p>Esta aplicação vem com uma série de ficheiros que fazem várias coisas, em maior parte, relacionadas com a configuração, mas existe um ficheiro que se destaca: <code>App.js</code>.</p><p><code>App.js</code> é o <strong>primeiro Componente do<strong> React</strong></strong> que vais conhecer.</p><p>Este é o código dele:</p><pre><code class="language-js">import React from 'react'
import logo from './logo.svg'
import './App.css'

function App() {
  return (
    &lt;div className="App"&gt;
      &lt;header className="App-header"&gt;
        &lt;img src={logo} className="App-logo" alt="logo" /&gt;
        &lt;p&gt;
          Edit &lt;code&gt;src/App.js&lt;/code&gt; and save to reload.
        &lt;/p&gt;
        &lt;a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        &gt;
          Learn React
        &lt;/a&gt;
      &lt;/header&gt;
    &lt;/div&gt;
  )
}

export default App
</code></pre><p>Uma aplicação criada utilizando React, ou um dos outros <em>frameworks </em>de front-end populares, como Vue e Svelte, por exemplo, é criada utilizando dezenas de componentes.</p><p>Vamos começar, no entanto, por analisar o primeiro componente. Vou simplificar o código deste componente, assim:</p><pre><code class="language-js">import React from 'react'
import logo from './logo.svg'
import './App.css'

function App() {
  return /* algo */
}

export default App
</code></pre><p>Podes ver algumas coisas aqui. <em>I<em>mpor</em>tamos</em> algumas coisas e <em><em>expor</em>tamos</em> uma função chamada <code>App</code>.</p><p>As coisas que importamos são, neste caso, uma biblioteca do JavaScript (o pacote de npm <code>react</code>), uma imagem SVG e um ficheiro CSS.</p><blockquote><code><em><em>create-react-app</em></em></code><em><em> </em>está configurado num modo que nos permite importar imagens e <em>CSS </em>para utilizar no nosso<em> JavaScript, </em>mas isto não é algo que tenhamos de nos preocupar para já<em>. </em>O que precisas de te preocupar é o conceito de um<em> </em></em><strong><strong><em><em>component</em></em></strong><em>e</em></strong></blockquote><p><code>App</code> é uma função que, no exemplo original, retorna algo que, à primeira vista, tem um aspeto muito estranho.</p><p>Parece ser <strong><strong>HTML</strong></strong> mas tem algum JavaScript incorporado.</p><p>Isto é <strong><strong>JSX</strong></strong>, uma linguagem especial que utilizamos para criar o resultado de um componente. Vamos falar mais sobre o JSX na próxima secção.</p><p>Para além de definir algum JSX para ser retornado, um componente tem muitas outras características.</p><p>Um componente pode ter o seu próprio <strong><strong><em>state</em></strong></strong>, que significa que encapsula algumas variáveis que outros componentes não conseguem aceder, a não ser que este componente exponha o <em>state</em> para a restante aplicação.</p><p>Um componente também pode receber dados de outros componentes. Neste caso, estamos a falar sobre <strong><strong><em>props</em></strong></strong>.</p><p>Não te preocupes, em breve vamos olhar com mais detalhes para todos estes termos (JSX, State e Props).</p><h2 id="introdu-o-ao-jsx"><strong>Introdução ao JSX</strong></h2><p>Não podemos falar sobre React sem explicar primeiro o JSX.</p><p>Na última secção, ficaste a conhecer o teu primeiro componente React, o componente <code>App</code> definido na aplicação predefinida criada pelo <code>create-react-app</code>.</p><p>O seu código era o seguinte:</p><pre><code class="language-js">import React from 'react'
import logo from './logo.svg'
import './App.css'

function App() {
  return (
    &lt;div className="App"&gt;
      &lt;header className="App-header"&gt;
        &lt;img src={logo} className="App-logo" alt="logo" /&gt;
        &lt;p&gt;
          Edit &lt;code&gt;src/App.js&lt;/code&gt; and save to reload.
        &lt;/p&gt;
        &lt;a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        &gt;
          Learn React
        &lt;/a&gt;
      &lt;/header&gt;
    &lt;/div&gt;
  )
}

export default App
</code></pre><p>Anteriormente, ignoramos tudo o que estava dentro da instrução <code>return</code>, mas, nesta secção, vamos falar sobre isso.</p><p>Chamamos JSX a tudo o que esteja entre os parênteses do que é retornado pelo componente:</p><pre><code class="language-jsx">&lt;div className="App"&gt;
  &lt;header className="App-header"&gt;
    &lt;img src={logo} className="App-logo" alt="logo" /&gt;
    &lt;p&gt;
      Edit &lt;code&gt;src/App.js&lt;/code&gt; and save to reload.
    &lt;/p&gt;
    &lt;a
      className="App-link"
      href="https://reactjs.org"
      target="_blank"
      rel="noopener noreferrer"
    &gt;
      Learn React
    &lt;/a&gt;
  &lt;/header&gt;
&lt;/div&gt;
</code></pre><p>Isto <em>parece</em> HTML, mas não é realmente HTML. É um pouco diferente.</p><p>É um pouco estranho ter este código dentro de um ficheiro JavaScript. Isto não se parece nada com JavaScript!</p><p>Em segundo plano, o React irá processar o JSX e vai transformá-lo em JavaScript, que o navegador será capaz de interpretar.</p><p>Então, estamos a escrever JSX, mas, no final, existe um passo de tradução que o torna legível para um interpretador de JavaScript.</p><p>O React fornece-nos esta interface por uma razão: <strong>é mais fácil criar interfaces de<strong> UI </strong>utilizando<strong> JSX</strong></strong>.</p><p>Assim que estiveres mais à vontade com o JSX, claro.</p><p>Na próxima secção, vamos falar sobre como o JSX te permite compor facilmente uma UI, e depois vamos ver as diferenças em relação ao "HTML normal" que precisas saber.</p><h2 id="utilizar-jsx-para-compor-uma-ui"><strong>Utilizar JSX para compor uma UI</strong></h2><p>Tal como introduzido na secção anterior, um dos principais benefícios do JSX é que torna muito fácil criar uma UI.</p><p>Em particular, num componente do React, podes importar outros componentes do React e podes incorporá-los e exibi-los.</p><p>Um componente do React é geralmente criado no seu próprio ficheiro, porque é assim que podemos facilmente reutilizá-lo (ao importá-lo) em outros componentes.</p><p>Um componente do React, no entanto, também pode ser criado no mesmo ficheiro de outro componente, se planeares utilizá-lo apenas nesse componente. Aqui não existe uma "regra", podes fazer o que achares melhor.</p><p>Eu geralmente utilizo ficheiros separados quando o número de linhas fica muito grande.</p><p>Para manter as coisas simples, vamos criar um componente no mesmo ficheiro <code>App.js</code>.</p><p>Vamos criar um componente <code>WelcomeMessage</code>:</p><pre><code class="language-js">function WelcomeMessage() {
  return &lt;p&gt;Welcome!&lt;/p&gt;
}
</code></pre><p>Vês? É uma simples função que retorna uma linha de JSX, que representa um elemento de HTML <code>p</code>.</p><p>Vamos adicioná-lo ao ficheiro <code>App.js</code>.</p><p>Agora, dentro do componente de JSX <code>App</code>, podemos adicionar <code>&lt;WelcomeMessage /&gt;</code> para exibir este componente na interface de utilizador:</p><pre><code class="language-js">import React from 'react'
import logo from './logo.svg'
import './App.css'

function WelcomeMessage() {
  return &lt;p&gt;Welcome!&lt;/p&gt;
}

function App() {
  return (
    &lt;div className="App"&gt;
      &lt;header className="App-header"&gt;
        &lt;img src={logo} className="App-logo" alt="logo" /&gt;
        &lt;p&gt;
          Edit &lt;code&gt;src/App.js&lt;/code&gt; and save to reload.
        &lt;/p&gt;
        &lt;WelcomeMessage /&gt;
        &lt;a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        &gt;
          Learn React
        &lt;/a&gt;
      &lt;/header&gt;
    &lt;/div&gt;
  )
}

export default App
</code></pre><p>Aqui está o resultado. Consegues ver a mensagem "Welcome!" (em português, "boas-vindas") no ecrã?</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/11/new-component.png" class="kg-image" alt="new-component" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/11/new-component.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/11/new-component.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2023/11/new-component.png 1392w" sizes="(min-width: 720px) 720px" width="1392" height="1092" loading="lazy"></figure><p>Dizemos que <code>WelcomeMessage</code> é um <strong><strong>c</strong>omponente-filho</strong> de App, e <code>App</code> é o seu <strong>componente-pai</strong>.</p><p>Vamos adicionar o componente <code>&lt;WelcomeMessage /&gt;</code> como se fizesse parte da linguagem HTML.</p><p>Esta é a beleza dos componentes React e do JSX: podemos compor uma interface de uma aplicação e utilizá-la como se estivéssemos a escrever HTML.</p><p>Com algumas diferenças, como veremos na próxima secção.</p><h2 id="a-diferen-a-entre-jsx-e-html"><strong>A diferença entre JSX e HTML</strong></h2><p>O JSX parece mais ou menos HTML, mas não é.</p><p>Neste secção, quero apresentar-te algumas das coisas mais importantes que precisas ter em mente ao utilizar o JSX.</p><p>Uma das diferenças pode ser bastante óbvia se observaste o componente de JSX <code>App</code>: existe um atributo estranho chamado <code>className</code>.</p><p>Em HTML, utilizamos o atributo <code>class</code>. É provavelmente o atributo mais utilizado, por várias razões. Uma dessas razões é o CSS. O atributo <code>class</code> permite-nos estilizar facilmente elementos de HTML. Frameworks de CSS, como o Tailwind, colocam este atributo no centro do processo de design em CSS da interface de utilizador.</p><p>Existe um problema, contudo. Estamos a escrever o código desta UI num ficheiro de JavaScript e o atributo <code>class</code> na linguagem de programação JavaScript é uma palavra reservada. Isto quer dizer que não podemos utilizar esta palavra reservada como quisermos. Ela serve um propósito específico (definir classes de JavaScript) e os criadores do React tiveram de escolher um nome diferente.</p><p>Foi assim que acabamos com <code>className</code> em vez de <code>class</code>.</p><p>Vais ter de memorizar isso, especialmente quando estiveres a copiar/colar algum HTML existente.</p><p>O React vai fazer o seu melhor para impedir que as coisas quebrem, mas irá criar uma série de alertas nas Ferramentas de Programador:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/11/className.png" class="kg-image" alt="className" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/11/className.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/11/className.png 776w" sizes="(min-width: 720px) 720px" width="776" height="156" loading="lazy"></figure><p>Esta não é a única funcionalidade do HTML que sofre deste problema, mas é uma das mais comuns.</p><p>Outra grande diferença entre JSX e HTML é que o HTML é muito <em><em>relax</em>ado</em>, digamos. Mesmo que tenhas um erro na sintaxe, ou tenhas fechado incorretamente uma tag, ou tenhas uma discrepância, o browser fará o seu melhor para tentar interpretar o HTML sem dar problemas.</p><p>É uma das principais funcionalidades da Web. É muito indulgente.</p><p>O JSX não perdoa. Se te esqueceres de fechar uma tag, receberás uma mensagem clara de erro:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/11/jsx-error.png" class="kg-image" alt="jsx-error" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/11/jsx-error.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/11/jsx-error.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2023/11/jsx-error.png 1057w" sizes="(min-width: 720px) 720px" width="1057" height="1092" loading="lazy"></figure><blockquote><em>O <em>React </em>geralmente fornece mensagens de erro muito boas e informativas que te apontam na direção correta para resolver o problema<em>.</em></em></blockquote><p>Outra grande diferença entre JSX e HTML é que em JSX podemos incorporar JavaScript.</p><p>Vamos falar sobre isto na próxima secção.</p><h2 id="incorporar-javascript-em-jsx"><strong>Incorporar JavaScript em JSX</strong></h2><p>Uma das melhores funcionalidades do React é que podemos facilmente incorporar JavaScript no JSX.</p><p>Outros <em>frameworks</em> de frontend, por exemplo Angular e Vue, têm as suas próprias formas específicas de imprimir valores JavaScript no <em>template</em>, ou realizar coisas como ciclos.</p><p>O React não adiciona coisas novas. Em vez disso, permite-nos utilizar JavaScript no JSX, ao utilizar chavetas.</p><p>O primeiro exemplo disto que te vou apresentar vem diretamente do componente <code>App</code> que temos estado a estudar até agora.</p><p>Importamos o ficheiro SVG <code>logo</code> utilizando o comando</p><pre><code class="language-js">import logo from './logo.svg'
</code></pre><p>e de seguida, no JSX, atribuímos este ficheiro SVG ao atributo <code>src</code> de uma tag <code>img</code>:</p><pre><code class="language-js">&lt;img src={logo} className="App-logo" alt="logo" /&gt;
</code></pre><p>Vamos fazer outro exemplo. Vamos supor que o componente <code>App</code> tem uma variável chamada <code>message</code>:</p><pre><code class="language-js">function App() {
  const message = 'Hello!'
  //...
}
</code></pre><p>Podemos imprimir este valor no JSX ao adicionar <code>{message}</code> em qualquer local do JSX.</p><p>Dentro das chavetas <code>{ }</code>, podemos adicionar qualquer instrução JavaScript, mas <em>apenas uma</em> instrução por cada bloco de chavetas.</p><p>Á instrução deve retornar algo.</p><p>Por exemplo, esta é uma instrução comum que irás encontrar em JSX. Temos um operador ternário onde definimos uma condição (<code>message === 'Hello!'</code>), e imprimimos um valor caso a condição seja verdadeira, ou outro valor (o conteúdo de <code>message</code>, neste caso) caso a condição seja falsa:</p><pre><code class="language-js">{
  message === 'Hello!' ? 'The message was "Hello!"' : message
}
</code></pre><h2 id="gerir-o-state-em-react"><strong>Gerir o <em>state</em> em React</strong></h2><p>Qualquer componente React pode ter o seu próprio <strong><strong><em>state</em></strong></strong>.</p><p>O que queremos dizer com <em><em>state</em></em>? O <em>state</em> é o <strong>conjunto de dados<strong> </strong>que é gerido pelo componente</strong>.</p><p>Imagina um formulário, por exemplo. Cada elemento <em>input</em> individual do formulário é responsável pela gestão do seu <em>state</em>: o que está escrito dentro dele.</p><p>Um botão está responsável por saber se está a ser clicado ou não. Se está a ser focado.</p><p>Um link está responsável por saber se o rato está por cima dele.</p><p>Em React, ou em qualquer framework/biblioteca com base em componentes, todas as nossas aplicações são baseadas e utilizam muito o <em>state</em> do componente.</p><p>Gerimos o <em>state</em> através do utilitário <code>useState</code> fornecido pelo React. É tecnicamente um <strong><strong><em>hook</em></strong></strong> (não precisas saber os detalhes dos <em>hooks</em> por enquanto, mas é o que isto é).</p><p>Importas o <code>useState</code> do React desta forma:</p><pre><code class="language-js">import React, { useState } from 'react'
</code></pre><p>Ao chamar <code>useState()</code>, irás receber uma nova variável de <em>state</em> e uma função que podemos chamar para alterar o seu valor.</p><p><code>useState()</code> aceita o valor inicial do item de <em>state</em> e retorna um array que contém a variável de <em>state</em> e a função que chamas para alterar o <em>state</em>.</p><p>Exemplo:</p><pre><code class="language-js">const [count, setCount] = useState(0)
</code></pre><p>Isto é importante. Não podemos simplesmente alterar diretamente o valor de uma variável de <em>state</em>. Temos de chamar a sua função de modificação. Caso contrário, o componente React não ira atualizar a sua UI para refletir as alterações feitas aos dados.</p><p>Chamar o modificador é a maneira com que podemos indicar ao React que o <em>state</em> de um componente foi alterado.</p><p>A sintaxe é um pouco estranha, não é? Visto que <code>useState()</code> retorna um array, utilizamos desestruturação de array para aceder a cada item individual, assim: <code>const [count, setCount] = useState(0)</code></p><p>Aqui está um exemplo prático:</p><pre><code class="language-js">import { useState } from 'react'

const Counter = () =&gt; {
  const [count, setCount] = useState(0)

  return (
    &lt;div&gt;
      &lt;p&gt;You clicked {count} times&lt;/p&gt;
      &lt;button onClick={() =&gt; setCount(count + 1)}&gt;Click me&lt;/button&gt;
    &lt;/div&gt;
  )
}

ReactDOM.render(&lt;Counter /&gt;, document.getElementById('app'))
</code></pre><p>Podes adicionar quantas chamadas <code>useState()</code> quiseres para criar quantas variáveis de <em>state</em> quiseres:</p><pre><code class="language-js">const [count, setCount] = useState(0)
const [anotherCounter, setAnotherCounter] = useState(0)
</code></pre><h2 id="props-de-componente-em-react"><strong><em>Props</em> de componente em React</strong></h2><p>Chamamos <code>props</code> aos valores iniciais passados para um componente.</p><p>Anteriormente, criamos um componente <code>WelcomeMessage</code></p><pre><code class="language-js">function WelcomeMessage() {
  return &lt;p&gt;Welcome!&lt;/p&gt;
}
</code></pre><p>e utilizamos o componente desta maneira:</p><pre><code class="language-js">&lt;WelcomeMessage /&gt;
</code></pre><p>Este componente não tem nenhum valor inicial. Não tem nenhum <em>prop</em>.</p><p>Os <em>props </em>podem ser passados como atributos para o componente no JSX:</p><pre><code class="language-js">&lt;WelcomeMessage myprop={'somevalue'} /&gt;
</code></pre><p>Dentro do componente, recebemos os <em>props </em>como argumentos:</p><pre><code class="language-js">function WelcomeMessage(props) {
  return &lt;p&gt;Welcome!&lt;/p&gt;
}
</code></pre><p>É comum utilizar desestruturação de objetos para obter os <em>props </em>pelo nome:</p><pre><code class="language-js">function WelcomeMessage({ myprop }) {
  return &lt;p&gt;Welcome!&lt;/p&gt;
}
</code></pre><p>Agora que temos o <em>prop</em>, podemos utilizá-lo dentro do componente. Por exemplo, podemos imprimir o seu valor no JSX:</p><pre><code class="language-js">function WelcomeMessage({ myprop }) {
  return &lt;p&gt;{myprop}&lt;/p&gt;
}
</code></pre><p>Aqui, as chavetas têm vários significados. No caso do argumento da função, as chavetas são utilizadas como parte da sintaxe de desestruturação do objeto.</p><p>De seguida, utilizamos as chavetas para definir o bloco de código da função, e por fim, no JSX, para imprimir o valor em JavaScript.</p><p>Passar <em>props </em>para os componentes é uma boa forma de transmitir valores na tua aplicação.</p><p>Um componente armazena dados (tem <em>state</em>) ou recebe dados através dos seus <em>props</em>.</p><p>Também podemos enviar funções como <em>props</em>. Por isso, um componente-filho pode chamar uma função no componente-pai.</p><p>Um <em>prop </em>especial, chamado <code>children</code>, contém o valor de tudo o que é passado entre as tags de abertura e de fecho do componente, por exemplo:</p><pre><code class="language-html">&lt;WelcomeMessage&gt; Here is some message &lt;/WelcomeMessage&gt;
</code></pre><p>Neste caso, dentro de <code>WelcomeMessage</code>, poderíamos aceder ao valor <code>Here is some message</code> ao utilizar o <em>prop </em><code>children</code>:</p><pre><code class="language-js">function WelcomeMessage({ children }) {
  return &lt;p&gt;{children}&lt;/p&gt;
}
</code></pre><h2 id="fluxo-de-dados-numa-aplica-o-em-react"><strong>Fluxo de dados numa aplicação em React</strong></h2><p>Numa aplicação em React, os dados geralmente fluem de um componente-pai para um componente-filho utilizando <em>props</em>, tal como vimos na secção anterior:</p><pre><code class="language-js">&lt;WelcomeMessage myprop={'somevalue'} /&gt;
</code></pre><p>Se passares uma função para o componente-filho, podes alterar o <em>state</em> do componente-pai a partir de um componente-filho:</p><pre><code class="language-js">const [count, setCount] = useState(0)

&lt;Counter setCount={setCount} /&gt;
</code></pre><p>Dentro do componente <em>Counter</em>, podemos agora pegar no prop <code>setCount</code> e chamá-lo para atualizar o <em>state</em> de <code>count</code> no componente-pai, quando algo acontece:</p><pre><code class="language-js">function Counter({ setCount }) {
  //...

  setCount(1)

  //...
}
</code></pre><p>É preciso saberes que existem formas mais avançadas de gerir dados, que incluem a API <em>Context</em> e bibliotecas como Redux. Estas formas, contudo, trazem mais complexidade. Em 90% das vezes, as duas maneiras que acabei de te explicar são a solução ideal.</p><h2 id="lidar-com-eventos-de-utilizador-em-react"><strong>Lidar com eventos de utilizador em React</strong></h2><p>O React fornece uma forma fácil de gerir eventos acionados a partir de eventos DOM, como cliques, eventos de formulário, entre outros.</p><p>Vamos falar sobre eventos de clique, que são bastante simples de digerir.</p><p>Podes utilizar o atributo <code>onClick</code> em qualquer elemento JSX:</p><pre><code class="language-js">&lt;button
  onClick={(event) =&gt; {
    /* gerir o evento */
  }}
&gt;
  Click here
&lt;/button&gt;
</code></pre><p>Quando o elemento é clicado, a função passada para o atributo <code>onClick</code> é acionada.</p><p>Podes definir esta função fora do JSX:</p><pre><code class="language-js">const handleClickEvent = (event) =&gt; {
  /* gerir o evento */
}

function App() {
  return &lt;button onClick={handleClickEvent}&gt;Click here&lt;/button&gt;
}
</code></pre><p>Quando o evento <code>click</code> é aciona no botão, o React chama a função do gestor de eventos.</p><p>O React suporta uma grande variedade de tipos de eventos, como <code>onKeyUp</code>, <code>onFocus</code>,<code>onChange</code>, <code>onMouseDown</code>, <code>onSubmit</code> e muito outros.</p><h2 id="eventos-de-ciclo-de-vida-num-componente-react"><strong>Eventos de ciclo de vida num componente React</strong></h2><p>Até agora, vimos como gerir o <em>state</em> com o <em>hook</em> <code>useState</code>.</p><p>Existe outro <em>hook</em> que te quero introduzir neste manual: <code>useEffect</code>.</p><p>O <em>hook</em> <code>useEffect</code> permite aos componentes terem acesso aos eventos de ciclo de vida de um componente.</p><p>Quando chamas o <em>hook</em>, passas-lhe uma função. A função será executada pelo React quando o componente é renderizado pela primeira vez, e em todas as re-renderizações/atualizações subsequentes.</p><p>O React atualiza primeiro o DOM, e depois chama qualquer função passada para <code>useEffect()</code>.</p><p>Tudo isto ocorre sem bloquear a renderização da UI, mesmo no código de bloqueio.</p><p>Aqui está um exemplo:</p><pre><code class="language-js">const { useEffect, useState } = React

const CounterWithNameAndSideEffect = () =&gt; {
  const [count, setCount] = useState(0)

  useEffect(() =&gt; {
    console.log(`You clicked ${count} times`)
  })

  return (
    &lt;div&gt;
      &lt;p&gt;You clicked {count} times&lt;/p&gt;
      &lt;button onClick={() =&gt; setCount(count + 1)}&gt;Click me&lt;/button&gt;
    &lt;/div&gt;
  )
}
</code></pre><p>Visto que a função <code>useEffect()</code> é executada em todas as renderizações/atualizações subsequentes de um componente, podemos dizer ao React para passá-la à frente, para efeitos de desempenho. Fazemos isto ao adicionar um segundo parâmetro que é um <em>array </em>que contém uma lista de variáveis de <em>state</em> a ter em atenção.</p><p>O React irá executar novamente o efeito secundário apenas se um dos itens neste <em>array </em>for alterado.</p><pre><code class="language-js">useEffect(() =&gt; {
  console.log(`Hi ${name} you clicked ${count} times`)
}, [name, count])
</code></pre><p>Da mesma maneira, podes dizer ao React para executar o efeito secundário apenas uma vez (no início), ao passar um <em>array </em>vazio:</p><pre><code class="language-js">useEffect(() =&gt; {
  console.log(`Component mounted`)
}, [])
</code></pre><p>Podes vir a utilizar essa opção muitas vezes.</p><p><code>useEffect()</code> é ótimo para adicionar registos, aceder a APIs externas, e muito mais.</p><h2 id="para-onde-seguir-a-partir-daqui"><strong>Para onde seguir a partir daqui</strong></h2><p>Dominar os tópicos explicados neste artigo é um grande passo no teu objetivo de aprender React.</p><p>Agora quero dar-te algumas dicas, porque é fácil perderes-te no mar de tutoriais e cursos sobre o React.</p><p>O que deves aprender a seguir? (os links citados pelo autor abaixo estão todos em inglês)</p><p>Aprende mais sobre o <a href="https://flaviocopes.com/react-virtual-dom/">DOM Virtual</a>, <a href="https://flaviocopes.com/react-declarative/">escrever código declarativo</a>, <a href="https://flaviocopes.com/react-unidirectional-data-flow/">fluxo de dados unidirecional</a>, <a href="https://flaviocopes.com/react-immutability/">imutabilidade</a>, <a href="https://flaviocopes.com/react-composition/">composição</a>.</p><p>Começa a criar algumas aplicações simples em React. Por exemplo, <a href="https://flaviocopes.com/react-example-counter/">cria um simples contador</a> ou uma <a href="https://flaviocopes.com/react-example-githubusers/">interação com uma API pública</a>.</p><p>Aprende como fazer <a href="https://flaviocopes.com/react-conditional-rendering/">renderizações condicionais</a>, como fazer <a href="https://flaviocopes.com/react-how-to-loop/">ciclos em JSX</a>, como utilizar as <a href="https://flaviocopes.com/react-developer-tools/">Ferramentas de Programador do React</a>.</p><p>Aprende como aplicar CSS numa aplicação em React, com <a href="https://flaviocopes.com/react-css/">CSS simples</a> ou <a href="https://flaviocopes.com/styled-components/">componentes estilizados</a>.</p><p>Aprende a gerir o <em>state</em> utilizando a <a href="https://flaviocopes.com/react-context-api/">API Context</a>, useContext e <a href="https://flaviocopes.com/redux/">Redux</a>.</p><p>Aprende como interagir com <a href="https://flaviocopes.com/react-forms/">formulários</a>.</p><p>Aprende como utilizar o <a href="https://flaviocopes.com/react-router/">Router do React</a>.</p><p>Aprende <a href="https://flaviocopes.com/react-testing-components/">como testar aplicações React</a>.</p><p>Aprende uma aplicação de <em>framework </em>construída sobre o React, como <a href="https://flaviocopes.com/gatsby/">Gatsby</a> ou <a href="https://flaviocopes.com/nextjs/">Next.js</a>.</p><p>Acima de tudo, não te esqueças de praticar ao criar aplicações simples para aplicar tudo o que aprendeste.</p><h2 id="conclus-o"><strong>Conclusão</strong></h2><p>Muito obrigado por leres este guia.</p><p>Espero que te inspire a aprender mais sobre o React e tudo o que podes fazer com ele!</p><p>Lembra-te que podes fazer <a href="https://flaviocopes.com/page/react-handbook/">download deste manual em PDF / ePub / e formato Mobi gratuitamente</a>, caso queiras.</p><p>O autor publica tutoriais de programação com frequência em seu site, <a href="https://flaviocopes.com/">flaviocopes.com</a>, se quiseres dar uma vista de olhos a outros bons conteúdos como este.</p><p>Podes entrar em contacto com o autor no Twitter: <a href="https://twitter.com/flaviocopes">@flaviocopes</a>.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como identificar e resolver renderizações desnecessárias no React ]]>
                </title>
                <description>
                    <![CDATA[ Escrito por: Nayeem Reza Recentemente, estive analisando o desempenho de uma aplicação do React na qual eu trabalhava e, de repente, pensei em definir algumas métricas de desempenho para essa aplicação. Com isso, descobri que a primeira coisa que precisaria resolver são as renderizações desnecessárias que estou fazendo em cada ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-identificar-e-resolver-renderizacoes-desnecessarias-no-react/</link>
                <guid isPermaLink="false">64f244c305a9d403ba833768</guid>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ana Laura Reis ]]>
                </dc:creator>
                <pubDate>Mon, 02 Oct 2023 02:13:23 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/1_PAy2dYBC4-B2JY9l4u4v4g.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/how-to-identify-and-resolve-wasted-renders-in-react-cc4b1e910d10/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to identify and resolve wasted renders in React</a>
      </p><p>Escrito por: Nayeem Reza</p><p>Recentemente, estive analisando o desempenho de uma aplicação do React na qual eu trabalhava e, de repente, pensei em definir algumas métricas de desempenho para essa aplicação. Com isso, descobri que a primeira coisa que precisaria resolver são as renderizações desnecessárias que estou fazendo em cada uma das páginas da web. Você pode estar se perguntando o que são renderizações desnecessárias, não é mesmo? Vamos aprofundar nisso.</p><p>Desde o começo, o React mudou toda a filosofia de criação de aplicações para a web e, consequentemente, o modo como pessoas que desenvolvem o <em>front-end</em> pensam. Com a introdução do <em>Virtual DOM</em>, o React torna as atualizações de interface do usuário mais eficiente e, com isso, a experiência da aplicação para a web se torna mais "limpa". </p><p>Você já se perguntou como deixar suas aplicações em React mais rápida? Por que aplicações para a web em React de tamanho moderado continuam tendo um desempenho ruim? O problema está no modo como utilizamos o React!</p><h3 id="como-o-react-funciona">Como o React funciona</h3><p>Uma biblioteca moderna de <em>front-end</em> como o <a href="https://react.dev/">React</a> não torna nossa aplicação magicamente mais rápida. Primeiro, nós, pessoas desenvolvedoras, devemos entender como o React funciona. Como os componentes atravessam os ciclos de vida ao longo da existência da aplicação? Portanto, antes de mergulharmos em qualquer técnica de otimização, precisamos entender melhor como o React realmente funciona nos bastidores.</p><p>Na essência do React, temos a sintaxe do JSX e a poderosa habilidade do React de construir e comparar <a href="https://reactkungfu.com/2015/10/the-difference-between-virtual-dom-and-dom/">V<em>irtual DOMs</em></a><em> (texto em inglês)</em>. Desde o seu lançamento, o React influenciou muitas outras bibliotecas de <em>front-end</em>. Por exemplo, o Vue.js também depende da ideia de V<em>irtual DOMs.</em></p><p>Cada aplicação do React começa com um componente raiz. Podemos pensar na aplicação inteira como uma estrutura em forma de árvore onde cada galho é um componente. Componentes no React são 'funções' que renderizam a interface do usuário com base nos dados, ou seja, nas <em>props</em> e no <em>state</em>. Podemos representar com: <code>CF</code> (componente funcional)</p><pre><code>UI = CF(dados)</code></pre><p>Usuários interagem com a interface e causam alterações nos dados. As interações são tudo que o usuário pode fazer na nossa aplicação. Exemplos disso são: clicar em um botão, ver um carrossel de imagens, fazer solicitações a APIs. Todas essas interações alteram apenas os dados. Elas nunca causam nenhuma alteração na interface.</p><p>Aqui, os dados desempenham um papel fundamental na definição do estado de uma aplicação. Não apenas o que armazenamos em nosso banco de dados. Mesmo diferentes estados na interface do usuário, como qual aba está atualmente selecionada ou se uma caixa de seleção está marcada ou não, fazem parte desses dados. Sempre que ocorre uma alteração nos dados, o React utiliza as funções do componente para recriar a interface do usuário, mas apenas virtualmente:</p><pre><code>UI1 = CF(dados1)
UI2 = CF(dados2)</code></pre><p>O React calcula a diferença entre a interface atual e a nova interface aplicando um <a href="https://reactjs.org/docs/reconciliation.html#the-diffing-algorithm" rel="noopener">algoritmo de comparação</a> (documentação em inglês) nas duas versões de seu <em>Virtual DOM</em>.</p><pre><code>Mudancas = Diferenca(UI1, UI2)</code></pre><blockquote>Nota da tradução: caso tente acessar a documentação apontada no parágrafo acima e mais abaixo, você verá que os links, agora, apontam para uma página de documentação legada. Ocorreram diversas mudanças tanto no React quanto em sua documentação a partir da versão 18, mas a explicação sobre o algoritmo de comparação ainda é válida para o entendimento do processo.</blockquote><p>Em seguida, o React prossegue aplicando apenas as alterações na interface do usuário (UI) real no navegador. Quando os dados associados a um componente mudam, o React determina se uma atualização na DOM "real" é necessária. Isso permite ao React evitar operações demoradas e que consomem muitos recursos no navegador, como a criação de elementos no DOM e a interação com elementos já existentes quando isso não é estritamente necessário.</p><p>Essa diferenciação e renderização repetida de componentes pode ser uma das principais fontes de problemas de desempenho no React. Criar uma aplicação em React na qual o algoritmo de diferenciação não consegue <a href="https://reactjs.org/docs/reconciliation.html">conciliar</a> (documentação em inglês) efetivamente, leva a uma renderização repetida de toda a aplicação, na verdade, resultando em <em>renderizações</em> desperdiçadas e podendo resultar em uma experiência lenta e frustrante.</p><p>Durante o processo de renderização inicial, o React constrói uma árvore DOM como esta:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/y4qB7PH40s9RK02BE5njs2w-lPMJVrKtqqor.png" class="kg-image" alt="y4qB7PH40s9RK02BE5njs2w-lPMJVrKtqqor" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/y4qB7PH40s9RK02BE5njs2w-lPMJVrKtqqor.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/y4qB7PH40s9RK02BE5njs2w-lPMJVrKtqqor.png 671w" width="671" height="346" loading="lazy"></figure><p>Suponha que uma parte dos dados mude. O que queremos que o React faça é renderizar novamente apenas os componentes que são diretamente afetados por essa mudança específica. Possivelmente, queremos que pule até mesmo o processo de diferenciação para o restante dos componentes. Vamos supor que alguns dados mudam no Componente <code>2</code> na imagem acima, e que esses dados foram passados de <code>R</code> para <code>B</code> e, depois, para <code>2</code>. Se <code>R</code> for renderizado novamente, ele também renderizará outra vez cada um de seus filhos (A, B, C e D). O que o React realmente faz é o seguinte:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/2X1HZDWVjVFi0fib0I9qUEEyeFIWLnBDcolg.png" class="kg-image" alt="2X1HZDWVjVFi0fib0I9qUEEyeFIWLnBDcolg" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/2X1HZDWVjVFi0fib0I9qUEEyeFIWLnBDcolg.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/2X1HZDWVjVFi0fib0I9qUEEyeFIWLnBDcolg.png 671w" width="671" height="346" loading="lazy"></figure><p>Na imagem acima, todos os nós amarelos são renderizados e diferenciados. Isso resulta em desperdício de tempo/recursos de computação. Aqui é onde concentrarmos principalmente nossos esforços de otimização. Configurando cada componente para renderizar e diferenciar apenas quando for necessário. Isso nos permitirá recuperar aqueles ciclos de CPU desperdiçados. Primeiro, veremos como identificar renderizações desnecessárias na nossa aplicação.</p><h3 id="identificar-renderiza-es-desnecess-rias"><strong>Id</strong>entificar renderizações desnecessárias</h3><p>Existem algumas maneiras diferentes de se fazer isso. O método mais simples é ativar a opção de <em><em>atualizações de destaque</em></em> na preferência de ferramentas de desenvolvimento do React.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/Rjxm5xSv-yo4igzgz4OhGUsyRobsIjnJMCTq.png" class="kg-image" alt="Rjxm5xSv-yo4igzgz4OhGUsyRobsIjnJMCTq" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/Rjxm5xSv-yo4igzgz4OhGUsyRobsIjnJMCTq.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/Rjxm5xSv-yo4igzgz4OhGUsyRobsIjnJMCTq.png 800w" sizes="(min-width: 720px) 720px" width="800" height="90" loading="lazy"></figure><p>Durante a interação com a sua aplicação, as atualizações são destacadas na tela com bordas coloridas. Você verá os componentes que foram renderizados novamente. Isso nos permite identificar novas renderizações que não eram necessárias.</p><p>Vamos seguir este exemplo:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/sEbzC97cYGA21Sap7VGKTlwNZ5OEBCDZwzD5.gif" class="kg-image" alt="sEbzC97cYGA21Sap7VGKTlwNZ5OEBCDZwzD5" width="600" height="333" loading="lazy"></figure><p>Observe que, quando inserimos uma segunda tarefa, a primeira tarefa também pisca na tela a cada tecla pressionada. Isso significa que ela está sendo renderizada novamente pelo React juntamente com a entrada. Chamamos esse acontecimento de renderização "desnecessária". Sabemos que é desnecessária porque o conteúdo da primeira tarefa não mudou, mas o React não sabe disso.</p><p>Mesmo que o React atualize apenas os nós do DOM que foram alterados, a nova renderização ainda leva algum tempo. Em muitos casos, isso não é um problema, mas, se a lentidão for perceptível, devemos considerar algumas coisas para impedir essas renderizações redundantes. </p><h3 id="usando-o-m-todo-shouldcomponentupdate"><strong>Usando o método <em>shouldComponentUpdate</em> </strong></h3><p>Por padrão, O React renderizará o virtual DOM e comparará a diferença de cada componente na árvore para qualquer alteração em suas <em>props</em> ou <em>state</em>. Isso, no entanto, não é uma boa opção. À medida que nossa aplicação cresce, tentar renderizar novamente e comparar toda virtual DOM em cada ação acabará tornando tudo mais lento.</p><p>O React, então, fornece um método de ciclo de vida simples para indicar se um componente precisa de uma nova renderização. Isso é feito através de <code>shouldComponentUpdate</code>, que é acionado antes do início do processo da nova renderização. A implementação padrão dessa função retorna <code>true</code>.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/M8-a8KtHWAtoicHp8-mmVkEd-FX-gqwZw6Co.png" class="kg-image" alt="M8-a8KtHWAtoicHp8-mmVkEd-FX-gqwZw6Co" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/M8-a8KtHWAtoicHp8-mmVkEd-FX-gqwZw6Co.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/M8-a8KtHWAtoicHp8-mmVkEd-FX-gqwZw6Co.png 800w" sizes="(min-width: 720px) 720px" width="800" height="236" loading="lazy"></figure><p>Quando essa função retorna <code>true</code> para qualquer componente, ela permite que o processo de diferenciação de renderização seja acionado. Isso nos dá o poder de controlar esse processo de diferenciação. Suponha que precisemos evitar que um componente seja renderizado novamente, precisamos apenas retornar <code>false</code> dessa função. Como podemos ver na implementação do método, podemos comparar as props e <em>state</em> atuais e próximos para determinar se uma nova renderização é necessária.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/5ERuL7iT4wDYhPCj9mmhSwp-cCch6ydPdNMJ.png" class="kg-image" alt="5ERuL7iT4wDYhPCj9mmhSwp-cCch6ydPdNMJ" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/5ERuL7iT4wDYhPCj9mmhSwp-cCch6ydPdNMJ.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/5ERuL7iT4wDYhPCj9mmhSwp-cCch6ydPdNMJ.png 800w" sizes="(min-width: 720px) 720px" width="800" height="236" loading="lazy"></figure><h3 id="uso-de-componentes-puros"><strong>Uso de componentes puros</strong></h3><p>Você já deve conhecer o <code>React.Component</code>, mas e <code>React.PureComponent</code>? Nós já falamos aqui sobre o método de ciclo de vida <code>shouldComponentUpdate</code>. Em componentes puros, já existe uma implementação padrão de <code>shouldComponentUpdate()</code> com uma comparação rasa de <em>props </em>e <em>state</em>. Portanto, um componente puro é um componente que apenas é renderizado novamente se as <em>props</em> e o <em>state</em> forem diferentes dos anteriores.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/jQnYm0ejA57POOcjmOJ1fauWWC7kB0q-y7Dr.png" class="kg-image" alt="jQnYm0ejA57POOcjmOJ1fauWWC7kB0q-y7Dr" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/jQnYm0ejA57POOcjmOJ1fauWWC7kB0q-y7Dr.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/jQnYm0ejA57POOcjmOJ1fauWWC7kB0q-y7Dr.png 800w" sizes="(min-width: 720px) 720px" width="800" height="258" loading="lazy"></figure><blockquote>Na comparação rasa, tipos de dados primitivos como string, booleano e número são comparados pelo seu valor, enquanto tipos de dados complexos como array, objeto e função são comparados pela referência.</blockquote><p>Se tivermos um componente funcional sem <em>state</em> em que precisamos implementar esse método de comparação antes que cada nova renderização ocorra, como podemos fazer isso? O React possui um Componente de Ordem Superior, chamado <code>React.memo</code>. É semelhante ao <code>React.PureComponent</code>, mas para componentes funcionais em vez de classes.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/A1MmnhyMmXvz-kwKx6619gJVx7IfUwMJGSKR.png" class="kg-image" alt="A1MmnhyMmXvz-kwKx6619gJVx7IfUwMJGSKR" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/A1MmnhyMmXvz-kwKx6619gJVx7IfUwMJGSKR.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/A1MmnhyMmXvz-kwKx6619gJVx7IfUwMJGSKR.png 800w" sizes="(min-width: 720px) 720px" width="800" height="357" loading="lazy"></figure><p>Por padrão, ele faz o mesmo que o <code>shouldComponentUpdate()</code>, que apenas compara superficialmente o objeto de <em>props</em>. Se, contudo, quisermos ter o controle sobre essa comparação, o que faremos? Também podemos fornecer uma função de comparação customizada como segundo argumento.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/38vWplvDxFSEpjSeL72vcNaLRs7XzBYwa1xI.png" class="kg-image" alt="38vWplvDxFSEpjSeL72vcNaLRs7XzBYwa1xI" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/38vWplvDxFSEpjSeL72vcNaLRs7XzBYwa1xI.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/38vWplvDxFSEpjSeL72vcNaLRs7XzBYwa1xI.png 800w" sizes="(min-width: 720px) 720px" width="800" height="561" loading="lazy"></figure><h3 id="tornar-os-dados-imut-veis">Tornar os dados imutáveis</h3><p><br>Poderíamos usar um <code>React.PureComponent</code> e ainda ter uma maneira eficiente de detectar automaticamente quando qualquer <em>prop</em> complexa ou <em>state </em>– como um <em>array</em>, objeto ou outras opções – fossem alterados? É aqui que a estrutura de dados imutáveis torna a vida mais fácil.</p><p>A ideia por trás do uso de estruturas de dados imutáveis é simples. Como falamos anteriormente, para tipos de dados complexos, a comparação é feita com base em suas referências. Sempre que um objeto contendo dados complexos é alterado, em vez de fazer as alterações nesse objeto, podemos criar uma cópia desse objeto com as alterações, o que criará uma referência.</p><p>O ES6 possui o operador de <em>spread</em> que torna isso possível.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/CbPn9o3eE53eh784JIzXPwaS7oqOefb-wW-O.png" class="kg-image" alt="CbPn9o3eE53eh784JIzXPwaS7oqOefb-wW-O" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/CbPn9o3eE53eh784JIzXPwaS7oqOefb-wW-O.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/CbPn9o3eE53eh784JIzXPwaS7oqOefb-wW-O.png 800w" sizes="(min-width: 720px) 720px" width="800" height="337" loading="lazy"></figure><p>Podemos fazer o mesmo com <em>arrays</em>:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/n73IBFev-5etKfGYTOAH-qAs8R3E6EICcaSv.png" class="kg-image" alt="n73IBFev-5etKfGYTOAH-qAs8R3E6EICcaSv" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/n73IBFev-5etKfGYTOAH-qAs8R3E6EICcaSv.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/n73IBFev-5etKfGYTOAH-qAs8R3E6EICcaSv.png 800w" sizes="(min-width: 720px) 720px" width="800" height="344" loading="lazy"></figure><h3 id="evite-passar-uma-nova-refer-ncia-para-os-mesmos-dados-antigos">Evite passar uma nova referência para os mesmos dados antigos</h3><p>Sabemos que sempre que <code>props</code> de um componente mudam, uma nova renderização acontece. Às vezes, porém, as <code>props</code> não mudam. Escrevemos o código de um modo que o React pensa que mudou, e isso acaba causando uma nova renderização. Dessa vez, no entanto, é uma renderizacão desnecessária. Então, basicamente, precisamos garantir que estamos passando uma referência diferente como <em>props</em> para dados diferentes. Além disso, precisamos evitar passar uma nova referência para os mesmos dados. Agora, vamos analisar alguns casos em que estamos criando esse problema. Veja o código abaixo:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/qDjrVvrQAPlavtw0rQGE05jPWXFvP8unpt9n.png" class="kg-image" alt="qDjrVvrQAPlavtw0rQGE05jPWXFvP8unpt9n" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/qDjrVvrQAPlavtw0rQGE05jPWXFvP8unpt9n.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/qDjrVvrQAPlavtw0rQGE05jPWXFvP8unpt9n.png 800w" sizes="(min-width: 720px) 720px" width="800" height="788" loading="lazy"></figure><p>Aqui está o conteúdo do componente <code>BookInfo</code>, onde estamos renderizando dois componentes, <code>BookDescription</code> e <code>BookReview</code>. Esse é o código correto e funciona bem, mas há um problema. <code>BookDescription</code> será renderizado novamente sempre que recebermos novos dados de avaliações como <em>props</em>. Por quê? Assim que o componente <code>BookInfo</code> recebe novas <em>props</em>, a função <code>render</code> é chamada para criar a sua árvore de elementos. A função de renderização cria uma constante <code>book</code>, o que significa criar outra referência. Portanto, <code>BookDescription</code> receberá <code>book</code> como uma nova referência, o que causará uma nova renderização de <code>BookDescription</code>. Para resolver isso, vamos refatorar esse código do seguinte modo: </p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/ushbIP1Vt8uV63TFX6DGyQAQZpIoNiW7BzPg.png" class="kg-image" alt="ushbIP1Vt8uV63TFX6DGyQAQZpIoNiW7BzPg" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/ushbIP1Vt8uV63TFX6DGyQAQZpIoNiW7BzPg.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/ushbIP1Vt8uV63TFX6DGyQAQZpIoNiW7BzPg.png 800w" sizes="(min-width: 720px) 720px" width="800" height="788" loading="lazy"></figure><p>Agora, a referência é sempre a mesma, <code>this.book</code>. Um outro objeto não é criado durante a renderização. Essa filosofia de nova renderização se aplica a todas as <em>props</em>, incluindo eventos, como abaixo:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/xmUdrbVqtYaa37e1Ds4ykJRiZRzpsQweDUVz.png" class="kg-image" alt="xmUdrbVqtYaa37e1Ds4ykJRiZRzpsQweDUVz" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/xmUdrbVqtYaa37e1Ds4ykJRiZRzpsQweDUVz.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/xmUdrbVqtYaa37e1Ds4ykJRiZRzpsQweDUVz.png 800w" sizes="(min-width: 720px) 720px" width="800" height="936" loading="lazy"></figure><p>Aqui, usamos duas maneiras diferentes (vincular métodos e usar uma <em>arrow function</em> na renderização) para chamar os métodos manipuladores de eventos, mas ambas criarão uma função sempre que o componente for renderizado novamente. Para resolver esses problemas, podemos vincular o método no <code>constructor</code> e usar propriedades de classe, o que ainda é experimental e não padronizado, mas muitos desenvolvedores já estão usando para passar funções para outros componentes em aplicações prontas para produção:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/wTadfqSaGeRy7nH-jSt2-285fbZGi2Zoy9rH.png" class="kg-image" alt="wTadfqSaGeRy7nH-jSt2-285fbZGi2Zoy9rH" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/wTadfqSaGeRy7nH-jSt2-285fbZGi2Zoy9rH.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/wTadfqSaGeRy7nH-jSt2-285fbZGi2Zoy9rH.png 800w" sizes="(min-width: 720px) 720px" width="800" height="1086" loading="lazy"></figure><h3 id="conclus-o">Conclusão</h3><p>Internamente, o React utiliza diversas técnicas inteligentes para minimizar a quantidade de operações custosas no DOM e necessárias para atualizar a interface do usuário. Para muitas aplicações, o uso do React resultará em uma interface de usuário rápida sem a necessidade de fazer muito trabalho para otimizar o desempenho especificamente. No entanto, se conseguirmos seguir as técnicas que mencionei acima para resolver as renderizações desnecessárias, então, para aplicações grandes, também teremos uma experiência muito fluida em termos de desempenho.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como configurar e fazer o deploy da sua aplicação React do zero usando o Webpack e o Babel ]]>
                </title>
                <description>
                    <![CDATA[ > Nota de tradução: assim como em outros artigos mais antigos sobre React, enfatizamos que, a partir da versão 18 do React, muitas modificações ocorreram e é possível que, tendo a versão mais recente instalada, as configurações feitas neste projeto não funcionem. Para o projeto funcionar, é preciso a instalação ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-configurar-e-fazer-o-deploy-da-sua-aplicacao-react-do-zero-usando-o-webpack-e-o-babel/</link>
                <guid isPermaLink="false">64e7470278917103e8a165e9</guid>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Felipe Archanjo ]]>
                </dc:creator>
                <pubDate>Tue, 26 Sep 2023 15:21:25 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/1_NluDivebM4nQi0OLMYuVHw.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/how-to-set-up-deploy-your-react-app-from-scratch-using-webpack-and-babel-a669891033d4/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to set up &amp; deploy your React app from scratch using Webpack and Babel</a>
      </p><blockquote>Nota de tradução: assim como em outros artigos mais antigos sobre React, enfatizamos que, a partir da versão 18 do React, muitas modificações ocorreram e é possível que, tendo a versão mais recente instalada, as configurações feitas neste projeto não funcionem. Para o projeto funcionar, é preciso a instalação da versão sugerida no projeto.</blockquote><p>Você já vem usando o <em>create-react-app</em>, também conhecido como CRA, há algum tempo. É ótimo e você pode começar a programar diretamente. Porém, quando você precisar sair do <em>create-react-app</em> e começar a configurar sua própria aplicação do React, haverá um momento em que precisará abrir mão do controle automático e começar a explorar por conta própria.</p><p>Este guia abordará uma configuração mais simples do React que, pessoalmente, tenho usado em quase todos os meus projetos com React. Ao final deste tutorial, teremos nosso próprio esqueleto (em inglês, <em>boilerplate</em>) pessoal e aprenderemos algumas configurações a partir dele.</p><h4 id="-ndice"><strong>Índice</strong></h4><ul><li>Por que criar sua própria configuração?</li><li>Configurando o Webpack 4</li><li>Configurando o Babel 7</li><li>Adicionando o Prettier</li><li>Adicionando mapa de origem para obter melhores logs de erro</li><li>Configurando o ESLint</li><li>Encontrei erros! O que faço agora?</li><li>Adicionando o processador de CSS LESS</li><li>Fazendo o <em>deploy </em>da aplicação do React no Netlify</li><li>Conclusão</li></ul><h3 id="por-que-criar-sua-pr-pria-configura-o">Por que criar sua própria configuração?</h3><p>Existem razões específicas que tornam a criação da sua própria configuração do React algo sensato a se fazer. Provavelmente, você já está familiarizado com o React e deseja aprender a usar ferramentas como o Webpack e o Babel por conta própria. Essas ferramentas de construção são poderosas. Se tiver um tempo extra, sempre é bom aprender mais sobre elas.</p><p>Os desenvolvedores são naturalmente pessoas curiosas. Se você sente que gostaria de saber como as coisas funcionam e qual parte faz o quê, deixe-me ajudá-lo com isso.</p><p>Além disso, ocultar a configuração do React por meio do <em>create-react-app</em> é voltado para desenvolvedores que estão começando a aprender React, já que a configuração não deve ser um obstáculo para começar. No entanto, quando as coisas ficam mais sérias, é claro que você precisa de mais ferramentas para integrar ao seu projeto. Pense em:</p><ul><li>Adicionar carregadores do Webpack para LESS e SASS</li><li>Realizar a renderização no lado do servidor</li><li>Usar novas versões do ES</li><li>Adicionar MobX e Redux</li><li>Criar sua própria configuração apenas para fins de aprendizado</li></ul><p>Se você procurar pela Internet, encontrará alguns truques para contornar as limitações do CRA, como o "<em>create-react-app rewired</em>". Por que não aprender a configurar o React por conta própria, no entanto? Eu vou ajudar você a chegar lá, passo a passo.</p><p>Agora que você está convencido a aprender um pouco sobre configuração, vamos começar iniciando um projeto em React do zero.</p><p>Abra o prompt de comando ou o Git bash e crie um diretório.</p><pre><code>mkdir react-config-tutorial &amp;&amp; cd react-config-tutorial</code></pre><p>Inicialize o projeto com o NPM executando:</p><pre><code>npm init -y</code></pre><p>Agora, instale o React:</p><pre><code>npm install react react-dom</code></pre><p>Além disso, você pode visualizar o código-fonte no GitHub enquanto lê este tutorial para obter explicações sobre as configurações.</p><h3 id="configurando-o-webpack-4">Configurando o Webpack 4</h3><blockquote>Nota da tradução: o próprio Webpack recomendado neste tutorial está na versão 4. No momento da tradução, a versão do Webpack é a versão 5.</blockquote><p>Nosso primeiro passo será configurar o Webpack. É uma ferramenta muito popular e poderosa para configurar não apenas o React, mas também quase todos os projetos de <em>front-end</em>. A função principal do Webpack é pegar vários arquivos JavaScript que escrevemos em nosso projeto e transformá-los em um único arquivo minificado, para que ele seja rápido de ser servido. A partir do Webpack 4, não é mais necessário escrever um arquivo de configuração para usá-lo, mas neste tutorial escreveremos um para entendermos melhor.</p><p>Primeiro, vamos fazer algumas instalações</p><pre><code>npm install --save-dev webpack webpack-dev-server webpack-cli</code></pre><p>Isso instalará:</p><ul><li><strong><strong>webpack</strong></strong> — que inclui todas as funcionalidades principais do Webpack</li><li><strong><strong>webpack-dev-server</strong></strong> — esse servidor de desenvolvimento executa automaticamente o Webpack novamente quando nosso arquivo é alterado</li><li><strong><strong>webpack-cli</strong></strong> — permite executar o Webpack a partir da linha de comando</li></ul><p>Vamos tentar executar o Webpack adicionando o seguinte script ao arquivo <code>package.json</code>:</p><pre><code class="language-js">"scripts": {
 "start": "webpack-dev-server --mode development",
},</code></pre><p>Agora, crie um arquivo <code>index.html</code> na raiz do seu projeto com o seguinte conteúdo:</p><pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html&gt;
 &lt;head&gt;
 &lt;title&gt;My React Configuration Setup&lt;/title&gt;
 &lt;/head&gt;
 &lt;body&gt;
 &lt;div id="root"&gt;&lt;/div&gt;
 &lt;script src="./dist/bundle.js"&gt;&lt;/script&gt;
 &lt;/body&gt;
&lt;/html&gt;</code></pre><p>Crie um diretório chamado <code>src</code> e, dentro dele, crie um arquivo chamado <code>index.js</code>.</p><pre><code>mkdir src &amp;&amp; cd src &amp;&amp; touch index.js</code></pre><p>Então, escreva um componente do React no arquivo:</p><pre><code class="language-js">import React from "react";
import ReactDOM from "react-dom";
class Welcome extends React.Component {
  render() {
    return &lt;h1&gt;Hello World from React boilerplate&lt;/h1&gt;;
  }
}
ReactDOM.render(&lt;Welcome /&gt;, document.getElementById("root"));</code></pre><p>Execute o Webpack usando <code>npm run start</code> … Ocorrerá um erro.</p><figure class="kg-card kg-code-card"><pre><code>You may need an appropriate loader to handle this file type</code></pre><figcaption>"Você pode precisar de um carregador adequado para lidar com esse tipo de arquivo"</figcaption></figure><h3 id="configurando-o-babel-7">Configurando o Babel 7</h3><p>O componente do React que escrevemos acima utilizou a sintaxe de <code>classe</code>, que é uma característica do ES6. O Webpack precisa do Babel para processar o ES6 em sintaxes do ES5, a fim de que essa classe funcione.</p><p>Vamos instalar o Babel no nosso projeto:</p><pre><code>npm install --save-dev @babel/core @babel/preset-env \@babel/preset-react babel-loader</code></pre><p>Por que precisamos desses pacotes?</p><ul><li><strong><strong>@babel/core</strong></strong> é a dependência principal que inclui o script de transformação do Babel.</li><li><strong><strong>@babel/preset-env</strong></strong> é o <em>preset </em>padrão do Babel usado para transformar ES6+ em código ES5 válido. Opcionalmente, configura automaticamente <em>polyfills </em>do navegador.</li><li><strong><strong>@babel/preset-react</strong></strong> é usado para transformar JSX e a sintaxe de classe do React em código JavaScript válido.</li><li><strong><strong>babel-loader</strong></strong> é um loader do Webpack que conecta o Babel ao Webpack. Vamos executar o Babel a partir do Webpack usando este pacote.</li></ul><p>Para integrar o Babel ao nosso Webpack, precisamos criar um arquivo de configuração do Webpack. Vamos criar um arquivo <code>webpack.config.js</code>:</p><pre><code class="language-js">module.exports = {
  entry: './src/index.js',
  output: {
    path: __dirname + '/dist',
    publicPath: '/',
    filename: 'bundle.js'
  },
  devServer: {
    contentBase: './dist',
  },
  module: {
    rules: [
    {
      test: /\.(js|jsx)$/,
      exclude: /node_modules/,
      use: ['babel-loader']
    }
    ]
  },
};</code></pre><p>Esta configuração do Webpack basicamente está dizendo que o ponto de entrada (em inglês, <code>entry)</code>) da nossa aplicação é <code>index.js</code>, então pegue tudo o que é necessário por esse arquivo e coloque a saída (em inglês, <code>output</code>) do processo de agrupamento (<em>bundling</em>) no diretório dist, com o nome <em><em>bundle.js</em></em>. Ah, se estivermos executando no <code>webpack-dev-server</code>, diga ao servidor para servir o conteúdo a partir da configuração <code>contentBase</code>, que é também o diretório onde a configuração está. Para os arquivos .js ou .jsx, utilize o <code>babel-loader</code> para transpilar todos eles.</p><p>Para usar os <em>presets </em>do Babel, crie um arquivo <code>.babelrc</code>.</p><pre><code>touch .babelrc</code></pre><p>Escreva o seguinte conteúdo:</p><pre><code class="language-js">{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react"
  ]
}</code></pre><p>Agora, execute <code>npm run start</code> novamente. Dessa vez, funcionará.</p><h3 id="adicionando-o-prettier"><strong><strong>Ad</strong>icionando o<strong> Prettier</strong></strong></h3><p>Para acelerar ainda mais o desenvolvimento, vamos criar um formatador de código usando o Prettier. Instale a dependência localmente e use o argumento --save-exact, já que o Prettier introduz mudanças estilísticas em lançamentos de correções.</p><pre><code>npm install --save-dev --save-exact prettier</code></pre><p>Agora, precisamos escrever o arquivo de configuração <code>.prettierrc</code>:</p><pre><code class="language-js">{
 "semi": true,
 "singleQuote": true,
 "trailingComma": "es5"
}</code></pre><p>As regras significam que queremos adicionar ponto e vírgula no final de cada instrução, usar aspas simples sempre que apropriado e adicionar vírgulas finais para código ES5 com várias linhas, como objetos ou <em>arrays</em>.</p><p>Você pode executar o Prettier a partir da linha de comando com:</p><pre><code>npx prettier --write "src/**/*.js"</code></pre><p>Também é possível adicionar um novo script ao arquivo <code>package.json</code>:</p><pre><code class="language-js">"scripts": {
 "test": "echo \"Error: no test specified\" &amp;&amp; exit 1",
 "start": "webpack-dev-server --mode development",
 "format": "prettier --write \"src/**/*.js\""
},</code></pre><p>Agora, podemos executar o Prettier usando <code>npm run format</code>.</p><p>Além disso, se você estiver usando o VSCode para desenvolvimento, pode instalar a <a href="https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode" rel="noopener">extensão do Prettier</a> e executá-la toda vez que salvar suas alterações, adicionando esta configuração:</p><pre><code>"editor.formatOnSave": true</code></pre><h3 id="adicionando-mapa-de-origem-para-obter-melhores-logs-de-erro">Adicionando mapa de origem para obter melhores logs de erro </h3><p>Uma vez que o Webpack empacota o código, os mapas de origem são obrigatórios para obter uma referência ao arquivo original que gerou um erro. Por exemplo, se você empacotar três arquivos de origem (<code>a.js</code>, <code>b.js</code>, e <code>c.js</code>) em um único pacote (<code>bundler.js</code>) e um dos arquivos de origem contiver um erro, o rastreamento de pilha simplesmente apontará para <code>bundle.js</code>. Isso é problemático, pois você provavelmente deseja saber exatamente se é o arquivo a, b ou c que está causando um erro.</p><p>Você pode instruir o Webpack a gerar mapas de origem usando a propriedade <strong>devtool</strong> na configuração:</p><pre><code class="language-js">module.exports = {
  devtool: 'inline-source-map',
  // … o resto da configuração
};</code></pre><p>Embora isso possa tornar a compilação mais lenta, não afeta a produção. Os <em>sourcemaps</em> só são baixados <a href="https://stackoverflow.com/a/44316255" rel="noopener">se você abrir as ferramentas de desenvolvimento do navegador (DevTools</a>) (texto em inglês).</p><h3 id="configurando-o-eslint">Configurando o ESLint</h3><p>Um <em>linter</em> é um programa que verifica nosso código em busca de erros ou avisos que possam causar bugs. O linter do JavaScript, o ESLint, é um programa de <em>linting</em> muito flexível que pode ser configurado de várias maneiras.</p><p>Antes de prosseguirmos, contudo, vamos instalar o ESLint em nosso projeto:</p><pre><code>npm --save-dev install eslint eslint-loader babel-eslint eslint-config-react eslint-plugin-react</code></pre><ul><li>O<strong> <strong>eslint</strong></strong> é a dependência principal para todas as funcionalidades, enquanto o eslint-loader nos permite integrar o eslint ao Webpack. Agora, como o React usa a sintaxe ES6+, vamos adicionar o <strong><strong>babel-eslint</strong></strong> — um analisador que permite que o eslint verifique todos os códigos ES6+ válidos.</li><li><strong><strong>eslint-config-react</strong></strong> e <strong><strong>eslint-plugin-react</strong></strong> são ambos usados para permitir que o ESLint utilize regras pré-definidas.</li></ul><p>Como já temos o Webpack, só precisamos modificar a configuração ligeiramente:</p><pre><code class="language-js">module.exports = {
  // modify the module
  module: {
    rules: [{
      test: /\.(js|jsx)$/,
      exclude: /node_modules/,
      use: ['babel-loader', 'eslint-loader'] // include eslint-loader
    }]
  },
};</code></pre><p>Em seguida, crie um arquivo de configuração do ESLint chamado <code>.eslintrc</code> com este conteúdo:</p><pre><code>{
  "parser": "babel-eslint",
  "extends": "react",
  "env": {
    "browser": true,
    "node": true
  },
  "settings": {
    "react": {
      "version": "detect"
    }
  }
}</code></pre><p>A configuração basicamente está dizendo, <em>"Ei, ESLint, por favor, analise o código usando o</em> <em><em> <code>babel-eslint</code> </em>antes de verificá-lo e, ao fazer a verificação, verifique se todas as regras do nosso arquivo de configuração de regras do React estão sendo cumpridas. Pegue as variáveis globais do ambiente do navegador e do Node. Ah, e se for código do React, pegue a versão do próprio módulo. Desse modo, o usuário não precisará especificar a versão manualmente."</em></p><p>Em vez de especificar nossas próprias regras manualmente, simplesmente estendemos as regras do <code>react</code>, que foram disponibilizadas por <code>eslint-config-react</code> e <code>eslint-plugin-react</code>.</p><h3 id="encontrei-erros-o-que-fa-o-agora"><strong>Encontrei erros<strong>! </strong>O que faço agora<strong>?</strong></strong></h3><p>Infelizmente, a única maneira de realmente descobrir como corrigir erros do ESLint é olhando a documentação das regras. Há uma maneira rápida de corrigir erros do ESLint usando <code>eslint--fix</code>. Na verdade, isso é útil para uma correção rápida. Vamos adicionar um script ao nosso arquivo <code>package.json</code>:</p><pre><code class="language-js">"scripts": {
  "test": "echo \"Error: no test specified\" &amp;&amp; exit 1",
  "start": "webpack-dev-server --mode development",
  "format": "prettier --write \"src/**/*.js\"",
  "eslint-fix": “eslint --fix \"src/**/*.js\"", // the eslint script
  "build": "webpack --mode production"
},</code></pre><p>Em seguida, execute-o com <code>npm run eslint-fix</code>. Não se preocupe se você ainda não está muito familiarizado com o ESLint por enquanto. Você aprenderá mais sobre o ESLint à medida que o utilizar.</p><h3 id="adicionando-o-processador-de-css-less"><strong>Adicionando o processador de CSS LESS</strong></h3><p>Para adicionar o processador LESS à nossa aplicação do React, precisaremos dos pacotes <strong>less</strong> e <strong>loader </strong>do Webpack:</p><pre><code>npm install --save-dev less less-loader css-loader style-loader</code></pre><p>O <code>less-loader</code> compilará nosso arquivo <em>less</em> em CSS, enquanto o <code>css-loader</code> resolverá a sintaxe do CSS, como <code>import</code> or <code>url()</code>. O <code>style-loader</code> pegará nosso CSS compilado e o carregará na tag <code>&lt;style&gt;</code> em nosso pacote. Isso é ótimo para o desenvolvimento, pois nos permite atualizar nosso estilo instantaneamente, sem precisar atualizar o navegador.</p><p>Agora, vamos adicionar alguns arquivos de CSS para criar um diretório de estilo em <code>src/style</code></p><pre><code>cd src &amp;&amp; mkdir style &amp;&amp; touch header.less &amp;&amp; touch main.less</code></pre><p>Conteúdo do <code>header.less</code>:</p><pre><code class="language-js">.header {
  background-color: #3d3d;
}</code></pre><p>Conteúdo do <code>main.less</code>:</p><pre><code class="language-css">@import "header.less";
@color: #f5adad;
body {
  background-color: @color;
}</code></pre><p>Depois, importe nosso arquivo <code>main.less</code> do <code>index.js</code>:</p><pre><code>import "./style/main.less";</code></pre><p>Em seguida, atualize a propriedade <code>module</code> na configuração do Webpack:</p><pre><code class="language-js">module: {
  rules: [{
    test: /\.(js|jsx)$/,
    exclude: /node_modules/,
    use: ['babel-loader', 'eslint-loader']
  },
  {
    test: /\.less$/,
    use: [
      'style-loader',
      'css-loader',
      'less-loader',
    ],
  },
 ]
},</code></pre><p>Execute o script de <code>start</code> e estamos prontos para seguir em frente!</p><h3 id="fazendo-o-deploy-da-aplica-o-do-react-no-netlify"><strong>Fazendo o deploy da aplicação<strong> </strong>do <strong>React </strong>no<strong> Netlify</strong></strong></h3><p>Todas as aplicações precisam passar pelo processo de <em>deploy</em> na etapa final, e para aplicações do React, o <em>deploy</em> é muito fácil.</p><p>Primeiro, vamos alterar a saída de <em>build</em> e o <code>contentBase</code> de <code>dist</code> para <code>build</code> em nossa configuração do Webpack.</p><pre><code class="language-js">module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'build'), // change this
    publicPath: '/',
    filename: 'bundle.js'
  },
  devServer: {
    contentBase: "./build",
  },
//…</code></pre><p>Agora, vamos instalar um novo plug-in do Webpack, chamado <code>HtmlWebpackPlugin</code>.</p><pre><code>npm install html-webpack-plugin -D</code></pre><p>Esse plug-in gerará um arquivo <code>index.html</code> no mesmo diretório onde o nosso <code>bundle.js</code> é criado pelo Webpack. Nesse caso, estamos falando do diretório <code>build</code>.</p><p>Por que precisamos desse plug-in? Porque o Netlify requer que um único diretório seja definido como o diretório raiz. Por isso, não podemos usar o <code>index.html</code> em nosso diretório raiz com o Netlify. Você precisa atualizar sua configuração do Webpack para que fique assim:</p><pre><code class="language-js">const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
  entry: //…
  output: {
    //…
  },
  devServer: {
    contentBase: "./build",
  },
  module: {
    //…
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve('./index.html'),
    }),
  ]
};</code></pre><p>Não se esqueça de remover a tag <code>script</code> do seu <code>index.html</code>:</p><pre><code class="language-html">&lt;!DOCTYPE html&gt;&lt;html&gt;  &lt;head&gt;    &lt;title&gt;My React Configuration Setup&lt;/title&gt;  &lt;/head&gt;  &lt;body&gt;    &lt;div id="root"&gt;&lt;/div&gt;  &lt;/body&gt;&lt;/html&gt;&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;My React Configuration Setup&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div id="root"&gt;&lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;</code></pre><p>Agora, você pode testar a configuração com o comando <code>npm run build</code>. Uma vez concluído, faça o push do seu esqueleto (<em>boilerplate</em>) para um repositório do GitHub. É hora de fazer o <em>deploy</em> da nossa aplicação!</p><p>Vamos criar uma conta no <a href="https://netlify.com/" rel="noopener">Netlify</a>. Se você ainda não ouviu falar do Netlify antes, é um incrível serviço de hospedagem de sites estáticos que oferece todas as ferramentas necessárias para implantar um site estático gratuitamente. O que é um site estático? É um site criado a partir de um conjunto de páginas HTML estáticas, sem nenhum <em>back-end</em>. Nosso esqueleto (<em>boilerplate</em>) do React, como está agora, conta como um site estático, pois não configuramos nenhum <em>back-end</em> – sendo composto apenas por HTML e JavaScript.</p><p>Após se cadastrar, selecione "New site" do Git e escolha o GitHub como seu provedor de Git:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/WfWqORsZjfHKwOpZ63d-nZUC6N2FF9CPzDrg.png" class="kg-image" alt="WfWqORsZjfHKwOpZ63d-nZUC6N2FF9CPzDrg" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/09/WfWqORsZjfHKwOpZ63d-nZUC6N2FF9CPzDrg.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/09/WfWqORsZjfHKwOpZ63d-nZUC6N2FF9CPzDrg.png 800w" sizes="(min-width: 720px) 720px" width="800" height="365" loading="lazy"></figure><p>Você precisa conceder permissões para o Netlify e, em seguida, selecionar o repositório do seu esqueleto (boilerplate) do React.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/MtKFlYYRZVZ7JNcmP8AHiiDV5OLlJoy4hBk5.png" class="kg-image" alt="MtKFlYYRZVZ7JNcmP8AHiiDV5OLlJoy4hBk5" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/09/MtKFlYYRZVZ7JNcmP8AHiiDV5OLlJoy4hBk5.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/09/MtKFlYYRZVZ7JNcmP8AHiiDV5OLlJoy4hBk5.png 800w" sizes="(min-width: 720px) 720px" width="800" height="555" loading="lazy"></figure><p>Agora, você precisa inserir o comando de construção (<em>build</em>) e o diretório de publicação. Como você pode ver, é por isso que precisamos do <em>HtmlWebpackPlugin</em>, porque precisamos servir tudo a partir de um único diretório. Em vez de atualizar manualmente nosso arquivo <code>index.html</code> raiz para as alterações, simplesmente o geramos usando o plug-in.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/aecd4gyxtTE22EuPoHzXRe1yA9I9BqTaPfa1.png" class="kg-image" alt="aecd4gyxtTE22EuPoHzXRe1yA9I9BqTaPfa1" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/09/aecd4gyxtTE22EuPoHzXRe1yA9I9BqTaPfa1.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/09/aecd4gyxtTE22EuPoHzXRe1yA9I9BqTaPfa1.png 800w" sizes="(min-width: 720px) 720px" width="800" height="771" loading="lazy"></figure><p>Certifique-se de ter o mesmo comando que a captura de tela acima, ou sua aplicação pode não funcionar.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/T3GN2LRCZtTIfNNOSVPV-tKgrmlllnRVcmcs.png" class="kg-image" alt="T3GN2LRCZtTIfNNOSVPV-tKgrmlllnRVcmcs" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/09/T3GN2LRCZtTIfNNOSVPV-tKgrmlllnRVcmcs.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/09/T3GN2LRCZtTIfNNOSVPV-tKgrmlllnRVcmcs.png 800w" sizes="(min-width: 720px) 720px" width="800" height="506" loading="lazy"></figure><p>Assim que o status de deploy mudar para <code>published</code> (em português, publicado – número 2 acima), você pode acessar o nome de site aleatório que o Netlify atribuiu à sua aplicação (número 1).</p><p>Sua aplicação React foi implantada. Parabéns!</p><h3 id="conclus-o"><strong>Conclusão</strong></h3><p>Você acaba de criar o seu próprio esqueleto (<em>boilerplate</em>) de projeto em React e de implantá-lo ao vivo no Netlify. É verdade que não mergulhamos muito fundo nas configurações do Webpack, porque este <em>boilerplate</em> foi projetado para ser um ponto de partida genérico. Em alguns casos, quando precisamos de recursos avançados como renderização no lado do servidor, precisamos ajustar a configuração novamente.</p><p>Porém, fique tranquilo! Você chegou até aqui, o que significa que já compreende o que o Webpack, o Babel, o Prettier e o ESLint fazem. O Webpack possui muitos carregadores poderosos que podem ajudar em muitos casos que você encontrará com frequência ao construir uma aplicação para a web.</p><p>Além disso, estou atualmente escrevendo um livro para ajudar os desenvolvedores de software a aprender sobre o React, que você talvez queira <a href="https://sebhastian.com/react-distilled/" rel="noopener">dar uma olhada</a> (livro em inglês)!</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/3ZrRhRwWyXnRsvrtUyYmir0KVQEteEd5yi3G.jpeg" class="kg-image" alt="3ZrRhRwWyXnRsvrtUyYmir0KVQEteEd5yi3G" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/09/3ZrRhRwWyXnRsvrtUyYmir0KVQEteEd5yi3G.jpeg 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/09/3ZrRhRwWyXnRsvrtUyYmir0KVQEteEd5yi3G.jpeg 800w" sizes="(min-width: 720px) 720px" width="800" height="301" loading="lazy"></figure><p>Você também pode ler mais dos meus tutoriais sobre React em <a href="https://sebhastian.com/" rel="noopener">sebhastian.com</a>.</p> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
