<?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[ Ana Laura Reis - 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[ Ana Laura Reis - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/portuguese/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sat, 23 May 2026 13:53:45 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/portuguese/news/author/analaurareis/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <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="600" height="400" 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="600" height="400" 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[ O que é um Helm Chart? Um tutorial para iniciantes no Kubernetes ]]>
                </title>
                <description>
                    <![CDATA[ O Kubernetes [https://azure.microsoft.com/pt-br/products/kubernetes-service/?WT.mc_id=containers-19838-ludossan]  é uma ferramenta muito útil para desenvolvedores nativos da nuvem. No entanto, por si só, ele não abrange todos os aspectos – existem algumas coisas que o Kubernetes não consegue resolver ou que estão fora de seu escopo. Essa é uma das razões pelas quais os ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/o-que-e-um-helm-chart-um-tutorial-para-iniciantes-no-kubernetes/</link>
                <guid isPermaLink="false">64fbd71c7a00f703f731d3cb</guid>
                
                    <category>
                        <![CDATA[ Kubernetes ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ana Laura Reis ]]>
                </dc:creator>
                <pubDate>Tue, 16 Apr 2024 21:57:23 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/604640a8a7946308b768453d.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/what-is-a-helm-chart-tutorial-for-kubernetes-beginners/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">What is a Helm Chart? A Tutorial for Kubernetes Beginners</a>
      </p><p>O <a href="https://azure.microsoft.com/pt-br/products/kubernetes-service/?WT.mc_id=containers-19838-ludossan">Kubernetes</a> &nbsp;é uma ferramenta muito útil para desenvolvedores nativos da nuvem. No entanto, por si só, ele não abrange todos os aspectos – existem algumas coisas que o Kubernetes não consegue resolver ou que estão fora de seu escopo.</p><p>Essa é uma das razões pelas quais os projetos de código aberto são tão bons. Eles ajudam ferramentas incríveis a se tornarem ainda mais incríveis quando as combinamos com outras ferramentas incríveis de código aberto. Muitas vezes, essas ferramentas foram desenvolvidas com o único propósito de preencher lacunas. Uma dessas ferramentas é o Helm.</p><h2 id="o-que-o-helm"><strong>O que é o Helm?</strong></h2><p>O <a href="https://helm.sh/">Helm</a> é amplamente conhecido como o "gerenciador de pacotes do <a href="https://azure.microsoft.com/pt-br/products/kubernetes-service/?WT.mc_id=containers-19838-ludossan">Kubernetes</a>". Embora se apresente assim, seu funcionamento vai muito além de um simples gerenciador de pacotes. No entanto, vamos começar do início.</p><p>Helm é um projeto de código aberto que foi originalmente criado pela <a href="https://deislabs.io/">DeisLabs</a> e doado à <a href="https://azure.microsoft.com/blog/announcing-cncf/?WT.mc_id=containers-19838-ludossan">CNCF</a> (texto em inglês), que agora o mantém. O objetivo original do Helm era proporcionar aos usuários uma maneira melhor de gerenciar todos os arquivos YAML do <a href="https://azure.microsoft.com/pt-br/products/kubernetes-service/?WT.mc_id=containers-19838-ludossan">Kubernetes</a> que criamos em projetos no <a href="https://azure.microsoft.com/pt-br/products/kubernetes-service/?WT.mc_id=containers-19838-ludossan">Kubernetes</a>.</p><p>O caminho que o Helm seguiu para resolver esse problema foi criar Helm <a href="https://docs.microsoft.com/azure/aks/kubernetes-helm?WT.mc_id=containers-19838-ludossan"><strong><strong>Charts</strong></strong></a>. Cada <em>chart</em> (em português, algo como "gráfico") é um pacote com um ou mais arquivos de configuração do Kubernetes – um <em>chart</em> pode ter <em>charts</em> filhos e <em>charts</em> dependentes também.</p><p>Isso significa que o Helm instala toda a árvore de dependências de um projeto se você executar o comando de instalação para o <em>chart</em> de nível superior. Você precisa apenas de um único comando para instalar toda a sua aplicação, em vez de listar os arquivos para instalação via <code>kubectl</code>.</p><p>Os <em>charts</em> também permitem que você controle a versão dos arquivos de configuração, assim como fazemos com o Node.js ou qualquer outro pacote. Isso permite que você instale versões específicas do <em>chart</em>, o que significa manter configurações específicas para sua infraestrutura na forma de código.</p><p>O Helm também mantém todo o histórico de lançamento de todos os <em>charts</em>, para que você possa voltar para uma versão anterior se algo der errado.</p><p>O <a href="https://docs.microsoft.com/azure/aks/kubernetes-helm?WT.mc_id=containers-19838-ludossan">Helm</a> oferece suporte nativo ao <a href="https://azure.microsoft.com/services/kubernetes-service/?WT.mc_id=containers-19838-ludossan">Kubernetes</a>. Isso significa que você não precisa escrever nenhum arquivo de sintaxe complexa ou algo do tipo para começar a usar o Helm. Basta colocar seus arquivos de modelo em um novo <em>chart</em> e você está pronto para começar.</p><p>Porém, você pode se perguntar o porquê devemos usá-lo. Gerenciar manifestos de aplicações pode ser facilmente feito com algumas combinações de comandos.</p><h2 id="por-que-voc-deve-usar-o-helm">Por que você deve usar o Helm<strong>?</strong></h2><p>O Helm realmente se destaca onde o Kubernetes não consegue. Por exemplo, na criação de <em>templates</em>. <br>O escopo do projeto Kubernetes é lidar com seus contêineres para você, não com seus arquivos de <em>template</em> (em português, modelos).</p><p>Isso torna muito difícil a criação de arquivos verdadeiramente genéricos para serem usados por meio de uma grande equipe ou organização, com diferentes parâmetros que precisam ser definidos para cada arquivo.</p><p>Além disso, como você <em>versiona</em> informações sensíveis usando o Git quando os arquivos de modelo são texto simples?</p><p>A resposta: com os <em>templates</em>. O Helm permite que você adicione variáveis e use funções dentro de seus arquivos de modelo. Isso o torna perfeito para aplicações escaláveis que, em algum momento, precisarão ter seus parâmetros alterados. Vamos ver um exemplo:</p><p>Eu tenho um projeto de código aberto chamado <em>Zaqar</em>, um microsserviço de e-mail simples para Node.js, que se comunica com o SendGrid. O projeto é basicamente composto por um serviço, um <em>deployment</em> e um escalonamento automático.</p><p>Vamos pegar o arquivo de <em>deployment</em> como exemplo. Eu teria algo assim:</p><pre><code class="language-yaml">apiVersion: apps/v1
kind: Deployment
metadata:
  name: zaqar
  namespace: default
  labels:
    app: zaqar
    version: v1.0.0
    env: production
spec:
  replicas: 1
  selector:
    matchLabels:
      app: zaqar
      env: production
  template:
    metadata:
      labels:
        app: zaqar
        version: v1.0.0
        env: production
    spec:
      containers:
        - name: zaqar
          image: "khaosdoctor/zaqar:v1.0.0"
          imagePullPolicy: IfNotPresent
          env:
            - name: SENDGRID_APIKEY
              value: "MY_SECRET_KEY"
            - name: DEFAULT_FROM_ADDRESS
              value: "my@email.com"
            - name: DEFAULT_FROM_NAME
              value: "Lucas Santos"
          ports:
            - name: http
              containerPort: 3000
              protocol: TCP
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 250m
              memory: 256Mi</code></pre><p>Se eu quiser usar esse modelo em um <em>pipeline</em> de integração contínua (CI) ou publicá-lo no meu GitHub, precisarei substituir as partes variáveis por marcadores de posição. Assim, podemos substituir esses textos pelas informações necessárias.</p><p>Nesse caso, tanto a tag da versão, a etiqueta de ambiente e as variáveis de ambiente seriam substituídas por marcadores de posição, como mostrado abaixo:</p><pre><code class="language-yaml">apiVersion: apps/v1
kind: Deployment
metadata:
  name: zaqar
  namespace: default
  labels:
    app: zaqar
    version: #!VERSION!#
    env: #!ENV!#
spec:
  replicas: 1
  selector:
    matchLabels:
      app: zaqar
      env: #!ENV!#
  template:
    metadata:
      labels:
        app: zaqar
        version: #!VERSION!#
        env: #!ENV!#
    spec:
      containers:
        - name: zaqar
          image: "khaosdoctor/zaqar:#!VERSION!#"
          imagePullPolicy: IfNotPresent
          env:
            - name: SENDGRID_APIKEY
              value: "#!SENDGRID_KEY!#"
            - name: DEFAULT_FROM_ADDRESS
              value: "#!FROM_ADDR!#"
            - name: DEFAULT_FROM_NAME
              value: "#!FROM_NAME!#"
          ports:
            - name: http
              containerPort: 3000
              protocol: TCP
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 250m
              memory: 256Mi</code></pre><p>Agora podemos executar nosso <em>pipeline</em> de CI. Antes de fazer isso, contudo, precisamos substituir nossos marcadores de posição pelos valores reais.<br><br>Para isso, podemos usar o <code>sed</code> e sua sintaxe "super fácil" &nbsp;<code>sed</code> &nbsp;<code>s/#!PLACEHOLDER!#/substituicao/g</code> e aplicá-la até que tenhamos substituído todos os marcadores de posição. O comando final seria algo assim:</p><pre><code class="language-bash">cat deploy.yaml | \
    sed 's/#!ENV!#/production/g' | \
    sed 's/#!VERSION!#/v1.0.0/g' | \
    sed 's/#!SENDGRID_KEY!#/MyKey/g' | \
    sed 's/#!FROM_ADDR!#/my@email.com/g' | \
    sed 's/#!FROM_NAME!#/Lucas Santos/g'</code></pre><p>Por padrão, o <code>sed</code> imprime tudo no <code>stdout</code>. Então, podemos adicionar outro I para o <code>kubectl -f</code>, como <code>&lt;todo o comando anterior&gt; | kubectl -f -</code>. Desse modo, teremos nossa implantação no lugar. O único problema é que precisamos fazer o mesmo para todos os outros arquivos.</p><p>Agora, imagine um projeto maior, com muitas outras variáveis e marcadores de posição. Você provavelmente escreveria um script para fazer isso por você, não é mesmo? Esse script é o Helm.</p><p>Quando você cria um Chart (mais sobre isso posteriormente), temos uma árvore de diretórios específica que devemos seguir para que o Helm entenda o que queremos fazer. Dentro do diretório de modelos <code>templates</code>, podemos adicionar nossos arquivos de manifesto, com <code>go templating</code> nativo, assim</p><pre><code class="language-yaml">apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Values.name }}
  namespace: {{ default .Release.Namespace .Values.namespace }}
  labels:
    app: {{ .Values.name }}
    version: {{ .Values.image.tag }}
    env: {{ .Values.env }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app: {{ .Values.name }}
      env: {{ .Values.env }}
  template:
    metadata:
      labels:
        app: {{ .Values.name }}
        version: {{ .Values.image.tag }}
        env: {{ .Values.env }}
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: "khaosdoctor/zaqar:{{ .Values.image.tag }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          env:
            - name: SENDGRID_APIKEY
              value: {{ required "You must set a valid Sendgrid API key" .Values.environment.SENDGRID_APIKEY | quote }}
            - name: DEFAULT_FROM_ADDRESS
              value: {{ required "You must set a default from address" .Values.environment.DEFAULT_FROM_ADDRESS | quote }}
            - name: DEFAULT_FROM_NAME
              value: {{ required "You must set a default from name" .Values.environment.DEFAULT_FROM_NAME | quote }}
          ports:
            - name: http
              containerPort: 3000
              protocol: TCP
          resources:
            {{- toYaml .Values.resources | nindent 12 }}</code></pre><p>Todos esses valores podem ser obtidos de um arquivo <code>Values.yaml</code> (para valores padrão), ou você pode defini-los na linha de comando usando a flag <code>--set &lt;caminho&gt; valor</code>. </p><p>Se queremos instalar nosso <em>chart</em>, podemos emitir o seguinte comando</p><pre><code class="language-bash">helm upgrade --install --create-namespace myChart ./path/to/my/chart \
  --set image.tag=v1.0.0 \
  --set env=production \
  --set environment.SENDGRID_APIKEY=myKey \
  --set environment.DEFAULT_FROM_ADDRESS="my@email.com" \
  --set environment.DEFAULT_FROM_NAME="Lucas Santos"</code></pre><p>O Helm também nos permite usar funções dentro de nossos <em>deployments</em>. Assim, podemos ter funções padrões para recorrer a valores padrões se não forem preenchidos, como o <em>namespace</em>. Também podemos ter a função <code>required</code>, que exibe uma mensagem e falha na instalação do Chart se o valor não for fornecido, como é o caso de nossas variáveis de ambiente.</p><p>Há muitas outras funções úteis na documentação deles – confira. </p><p>Agora, somos capazes de gerenciar não apenas de modo mais eficiente os recursos de nossa aplicação, mas também de publicar esses recursos em um sistema de controle de versão de código aberto sem nenhum problema ou questão de segurança.</p><h2 id="como-criar-um-helm-chart">Como criar um Helm Chart</h2><p></p><p>É bem fácil criar um <em>chart</em> no Helm. Primeiro, você precisa ter o Helm instalado. Em seguida, basta digitar <code>helm create &lt;nome do chart&gt;</code> e ele criará um diretório preenchido com arquivos e outros diretórios. Esses arquivos são necessários para que o Helm crie um <em>chart</em>.</p><p>Vamos dar uma olhada mais detalhada em como é essa árvore de diretórios e quais são os arquivos dentro dela:</p><ul><li><strong><strong>chart.yaml:</strong></strong> aqui é onde você colocará as informações relacionadas ao seu <em>chart</em>. Isso inclui a versão do <em>chart</em>, o nome e a descrição, para que você possa encontrá-lo se o publicar em um repositório aberto. Nesse arquivo, você também poderá definir <a href="https://helm.sh/docs/topics/charts/#chart-dependencies">dependências</a> externas usando a chave <code>dependencies</code> (documentação em inglês). </li><li><strong><strong>values.yaml</strong></strong>: como vimos antes, este é o arquivo que contém os valores padrão para as variáveis.</li><li><strong><strong>templates (dir):</strong></strong> esse é o local onde você colocará todos os seus arquivos de manifesto. Tudo aqui será passado e criado no Kubernetes.</li><li><strong><strong>charts:</strong></strong> se o seu <em>chart</em> depender de outro <em>chart</em> que você possui, ou se você não quiser depender da biblioteca padrão do Helm (o registro padrão de onde o Helm baixa os <em>charts</em>), você pode trazer essa mesma estrutura dentro desse diretório. As dependências do <em>chart</em> são instaladas de baixo para cima, o que significa que se o <em>chart</em> A depende do <em>chart</em> B, e B depende do C, a ordem de instalação será C -&gt; B -&gt; A.</li></ul><p>Há outros campos, mas estes são os mais comuns e são os obrigatórios. Você pode dar uma olhada rápida no <a href="https://github.com/khaosdoctor/zaqar/tree/master/helm">repositório do Zaqar</a> para ver como podemos publicar <em>charts</em> de código aberto.</p><p>Um aviso rápido: ao instalar o Helm, certifique-se de estar instalando a versão 3. A versão 2 ainda funciona, mas precisa de um componente do lado do servidor chamado Tiller, que vincula sua instalação do Helm a um único cluster. O Helm 3 removeu essa necessidade com a adição de vários CRDs, mas não é suportado em todas as versões do Kubernetes.</p><h2 id="como-hospedar-um-helm-chart">Como hospedar um Helm Chart</h2><p>Ok, você criou seu <em>chart</em>, e agora? Precisamos baixar o repositório inteiro para instalar esses <em>charts</em>? Não! O Helm tem uma biblioteca pública para os <em>charts</em> mais usados, que funciona de modo semelhante ao Docker Hub.</p><p>Você também pode criar seu próprio repositório de <em>charts</em> e <a href="https://helm.sh/docs/topics/chart_repository/">hospedá-lo on-line</a> (documentação em inglês). O Helm bebe da mesma fonte que o HomeBrew, ou o Linux. Você pode acessar esses repositórios para baixar os <em>charts</em> contidos neles.</p><p>Uma vez que um repositório de <em>charts</em> é basicamente um arquivo <code>index.yaml</code> servido a partir de um servidor da web estático, você pode praticamente criar um repositório de <em>charts</em> de qualquer lugar.</p><p>Vamos pegar o Zaqar, por exemplo – ele está hospedado no GitHub Pages e é acessível por meio do <a href="https://lsantos.me/zaqar/helm/index.yaml">meu domínio</a>. Quando o Helm procura por um arquivo <code>index.yaml</code>, na verdade está procurando a lista de versões disponíveis desse <em>chart</em>, seus resumos SHA256 e a localização do arquivo empacotado <code>.tgz</code> para baixar o próprio <em>chart</em>. Isso é mais ou menos o que o NPM faz nos bastidores (de modo bastante simplificado).</p><p>Isso significa que você não precisa ter seu repositório clonado para sempre, e seus <em>charts</em> podem ser privados também. Você só precisa criar um repositório de <em>charts</em>.</p><p>Você pode até mesmo usar <a href="https://learn.microsoft.com/pt-br/azure/container-registry/container-registry-helm-repos?WT.mc_id=containers-19838-ludossan">serviços hospedados como o Azure CR</a> para fazer o trabalho, ou você pode ter uma solução completa chamada <a href="https://github.com/helm/chartmuseum">Chart Museum</a>, que permite armazenar seus <em>charts</em> e oferece uma interface de usuário organizada.</p><h2 id="conclus-o"><strong>Conclusão</strong></h2><p>O Helm veio para ficar. Ele ajudou e continuará a ajudar muitos desenvolvedores do Kubernetes por muito tempo.</p><p>Se você quer saber como usar o Helm, pode consultar a <a href="https://helm.sh/">documentação</a> deles, ou pode fazer este <a href="https://learn.microsoft.com/pt-br/training/modules/aks-app-package-management-using-helm/?WT.mc_id=containers-19838-ludossan">módulo de aprendizagem gratuito</a> sobre como implantar suas aplicações no Kubernetes de maneira fácil com o Helm.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como conectar seu contêiner do Docker do Microsoft SQL Server ao Azure Data Studio ]]>
                </title>
                <description>
                    <![CDATA[  Este guia mostra como usar o Docker para baixar uma imagem do MSSQL Server e executá-la. O Azure Data Studio é a ferramenta de banco de dados multiplataforma que usaremos para conectar nosso contêiner do Docker ao MSSQL e para executar instruções SQL.  No final, mostrarei como importar ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-conectar-seu-conteiner-do-docker-do-microsoft-sql-server-ao-azure-data-studio/</link>
                <guid isPermaLink="false">64f931ec9566cf03c3d5491c</guid>
                
                    <category>
                        <![CDATA[ Bancos de dados ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ana Laura Reis ]]>
                </dc:creator>
                <pubDate>Sun, 08 Oct 2023 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/Screen-Shot-2020-03-29-at-3.52.47-AM.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/cjn-how-to-connect-your-microsoft-sql-server-docker-container-with-azure-data-studio/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Connect your Microsoft SQL Server Docker Container with Azure Data Studio</a>
      </p><p><br>Este guia mostra como usar o Docker para baixar uma imagem do MSSQL Server e executá-la. O Azure Data Studio é a ferramenta de banco de dados multiplataforma que usaremos para conectar nosso contêiner do Docker ao MSSQL e para executar instruções SQL. </p><p>No final, mostrarei como importar um banco de dados para o sistema de arquivos do Docker para que você possa acessá-lo por meio do Azure Data Studio. </p><p>Confira outras dicas relacionadas aqui (em inglês):</p><ul><li><em><em><a href="https://www.freecodecamp.org/news/cjn-how-to-connect-your-aws-rds-microsoft-sql-server-using-azure-data-studio/">Como conectar seu AWS RDS Microsoft SQL Server usando Azure Data Studio</a></em></em></li><li><a href="https://www.freecodecamp.org/news/cjn-how-to-import-a-sample-database-to-your-aws-rds-microsoft-sql-server-using-s3/"><em><em>Como importar um banco de dados de amostra para seu Microsoft SQL Server AWS RDS usando S3</em></em></a></li></ul><p>Vamos abordar as tecnologias mencionadas abaixo:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-238.png" class="kg-image" alt="image-238" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/image-238.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/10/image-238.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2023/10/image-238.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-238.png 2000w" sizes="(min-width: 1200px) 1200px" width="2000" height="310" loading="lazy"></figure><ul><li>Banco de Dados: Microsoft SQL Server </li><li>Contêiner para baixar o mssql-server-demo: Docker </li><li>Instalador para o mssql-cli: Node.js (ambiente de execução)/Gerenciador de Pacotes do Node (NPM) </li><li>Ferramenta de banco de dados e interface gráfica: Azure Data Studio</li></ul><h2 id="como-criar-nosso-ambiente-com-o-docker">Como criar nosso ambiente com o Docker</h2><h3 id="instalar-o-docker"><strong>Instalar o Docker</strong></h3><p>Guia completo <a href="https://database.guide/how-to-install-sql-server-on-a-mac/">aqui</a> (em inglês):</p><ol><li>Baixe o Docker CE (Community Edition) para Mac <a href="https://store.docker.com/editions/community/docker-ce-desktop-mac?tab=description">aqui</a> .</li><li>Para instalar, clique duas vezes no arquivo .dmg e arraste o ícone do aplicativo Docker para o aplicativo de pasta.</li></ol><blockquote>Nota da tradução: para usuários de outras plataformas, como Windows e Linux, sugerimos o guia da própria Microsoft de instalação do SQL Server em português. Para o Docker, veja como instalar em outras plataformas <a href="https://docs.docker.com/desktop/install/windows-install/">aqui</a> e <a href="https://docs.docker.com/desktop/install/linux-install/">aqui</a>.</blockquote><h4 id="o-que-docker"><strong>O que é Docker?</strong></h4><p>O Docker é uma plataforma que permite que o software seja executado em seu próprio ambiente isolado. O SQL Server (a partir de 2017) pode ser executado no Docker em seu próprio contêiner isolado.</p><p>Uma vez que o Docker esteja instalado, você simplesmente faz o download - ou "puxa" - a Imagem Docker do SQL Server no Linux para o seu Mac e, em seguida, a executa como um contêiner do Docker. Este contêiner é um ambiente isolado que contém tudo o que o SQL Server precisa para funcionar.</p><h3 id="iniciar-o-docker"><strong>Iniciar o Docker</strong></h3><p>Abra seu aplicativo do Docker. Ele deve estar localizado na pasta Aplicativos.</p><h3 id="aumentar-a-mem-ria"><strong>Aumentar a memória</strong></h3><p>Por padrão, Docker terá 2GB de memória alocados para ele. O SQL Server precisa de pelo menos 3,25 GB. Para segurança, aumente para 4 GB, se puder. Já que esse é apenas um <em>"playground"</em>, 2 GB deverão ser suficientes.</p><h3 id="opcional-caso-queria-aumenta-o-tamanho-da-mem-ria-"><strong>Opcional – caso queria aumenta o tamanho da memória:</strong></h3><ol><li>Selecione <em>Preferences</em> no ícone pequeno do Docker no menu superior </li><li>Deslize o controle deslizante de memória para pelo menos 2 GB</li><li> Clique em <em>Apply</em> e <em>Restart</em></li></ol><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-245.png" class="kg-image" alt="image-245" width="498" height="692" loading="lazy"></figure><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-246.png" class="kg-image" alt="image-246" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/image-246.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-246.png 992w" sizes="(min-width: 720px) 720px" width="992" height="902" loading="lazy"></figure><h3 id="baixar-o-sql-server"><strong>Baixar o SQL Server</strong></h3><p>Abra uma janela no terminal e execute o seguinte comando: </p><pre><code class="language-terminal">sudo docker pull mcr.microsoft.com/mssql/server:2019-latest</code></pre><p>Isso baixará a imagem mais recente do SQL Server 2019 para Linux do Docker para o seu computador.</p><p>Você também pode verificar a <a href="https://hub.docker.com/_/microsoft-mssql-server">versão mais recente do contêiner</a> no site do Docker, se desejar.</p><h3 id="iniciar-a-imagem-do-docker"><strong>Iniciar a imagem do Docker </strong></h3><p>Execute o seguinte comando para iniciar uma instância da imagem do Docker que você acabou de baixar.</p><pre><code class="language-terminal">docker run -d --name sql_server_demo -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=really</code></pre><p>Exemplo de saída:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-254.png" class="kg-image" alt="image-254" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/image-254.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/10/image-254.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-254.png 1480w" sizes="(min-width: 720px) 720px" width="1480" height="704" loading="lazy"></figure><h3 id="verificar-o-cont-iner-do-docker-opcional-"><strong>Verificar o contêiner do Docker (opcional)</strong></h3><p>Você pode executar o seguinte comando para verificar se o contêiner do Docker está em execução:</p><pre><code class="language-terminal">docker ps</code></pre><p>Se estiver instalado e funcionando, deverá retornar algo assim:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-247.png" class="kg-image" alt="image-247" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/image-247.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/10/image-247.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2023/10/image-247.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w2400/2023/10/image-247.png 2400w" sizes="(min-width: 1200px) 1200px" width="2824" height="118" loading="lazy"></figure><p>Se você fechou acidentalmente seu aplicativo do Docker, abra seu terminal e digite:</p><pre><code class="language-terminal">docker start sql_server_demo</code></pre><h3 id="instalar-o-node-js-e-o-npm"><strong>Instalar o Node.js e o NPM</strong></h3><p>Verifique se você possui o Node.js e o NPM. Execute os seguintes comandos em seu terminal.</p><pre><code class="language-terminal">node -v
npm -v</code></pre><p>Se a saída foi o número da versão, pule o restante desta seção.</p><p>Em seguida, visite o site do Node.js clicando no seguinte link:</p><p><a href="https://nodejs.org/en/">https://nodejs.org/en/</a></p><p>Clique no botão de download da versão LTS (o número da versão pode ser diferente) para baixar o pacote Node.js:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-249.png" class="kg-image" alt="image-249" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/image-249.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/10/image-249.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2023/10/image-249.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-249.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="434" loading="lazy"></figure><p>Em seguida, clique e execute o pacote após o download. MacOS e Windows terão processos de instalação diferentes. Siga as instruções para instalar o Node.js.</p><p>Em seguida, teste novamente se o Node.js e o NPM foram instalados com sucesso executando os seguintes comandos no terminal:</p><pre><code class="language-terminal">node -v
npm -v</code></pre><p>A saída deverá ser algo assim:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-248.png" class="kg-image" alt="image-248" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/image-248.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-248.png 884w" sizes="(min-width: 720px) 720px" width="884" height="154" loading="lazy"></figure><h3 id="instalar-o-sql-cli"><strong>Instalar o sql-cli</strong></h3><p>Execute o seguinte comando para instalar a ferramenta de linha de comando do sql-cli. Essa ferramenta permite que você execute consultas e outros comandos em sua instância do SQL Server.</p><pre><code class="language-terminal">npm install -g sql-cli</code></pre><p>Se houver algum erro de permissão, digite <code>sudo</code> antes do comando:</p><pre><code class="language-terminal">sudo npm install -g sql-cli</code></pre><h2 id="conectar-se-ao-mssql-server"><strong>Conectar-se ao MSSQL Server</strong></h2><p>Conecte-se ao seu SQL Server usando o comando <code>mssql</code>, seguido dos parâmetros de nome de usuário e senha. Sintaxe: &nbsp;-u &lt;nome de usuário&gt; -p &lt;senha&gt;</p><pre><code class="language-terminal">mssql -u sa -p reallyStrongPwd123</code></pre><p>Sua saída deverá ser assim, se você se conectar com sucesso:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-250.png" class="kg-image" alt="image-250" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/image-250.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/10/image-250.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-250.png 1352w" sizes="(min-width: 720px) 720px" width="1352" height="236" loading="lazy"></figure><h3 id="executar-um-teste-r-pido"><strong>Executar um teste rápido</strong></h3><p>Execute um teste rápido para verificar se você consegue se conectar ao SQL Server. Use a seguinte instrução SQL para verificar sua versão do SQL Server:</p><pre><code class="language-sql">SELECT @@VERSION;</code></pre><p>Se estiver em execução, você deverá ver algo assim:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-251.png" class="kg-image" alt="image-251" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/image-251.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/10/image-251.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-251.png 1288w" sizes="(min-width: 720px) 720px" width="1288" height="534" loading="lazy"></figure><h2 id="baixar-uma-gui-do-sql-server-azure-data-studio"><strong>Baixar uma GUI do SQL Server – Azure Data Studio</strong></h2><p><a href="https://database.guide/what-is-azure-data-studio/">O Azure Data Studio</a> (anteriormente SQL Operations Studio) é uma ferramenta gratuita de gerenciamento de GUI que você pode usar para gerenciar o SQL Server em seu computador. Você pode usá-lo para criar e gerenciar bancos de dados, escrever consultas, fazer backup e restaurar bancos de dados e muito mais.</p><p>O Azure Data Studio está disponível para Windows, Mac e Linux.</p><h3 id="instalar-o-azure-data-studio"><strong>Instalar o Azure Data Studio</strong></h3><p>Para instalar o Azure Data Studio em seu Mac:</p><ol><li>Visite a <a href="https://docs.microsoft.com/en-us/sql/azure-data-studio/download">página de download do Azure Data Studio</a> (em inglês – você pode encontrar a versão para as plataformas Windows e Linux na mesma página) e clique no arquivo .zip para macOS</li><li>Assim que o download do arquivo .zip para conclusão, clique duas vezes nele para expandir seu conteúdo</li><li>Arraste o arquivo .app para a pasta Aplicativos (o arquivo provavelmente será chamado <em><em>Azure Data Studio.app</em></em> )</li></ol><h3 id="conectar-se-ao-sql-server"><strong>Conectar-se ao SQL Server</strong></h3><p>Agora que o Azure Data Studio está instalado, você pode usá-lo para se conectar ao SQL Server.</p><ol><li>Inicie o Azure Data Studio. Ele está localizado na pasta Aplicativos.</li><li>Insira as credenciais de login e outras informações da instância do SQL Server à qual você deseja se conectar:</li></ol><p>Deve ser semelhante a isto:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-259.png" class="kg-image" alt="image-259" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/image-259.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/10/image-259.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-259.png 1064w" width="1064" height="739" loading="lazy"></figure><p>Deve ser semelhante a isto:</p><ul><li><strong><strong>Nome do servidor</strong></strong> : localhost, [número da porta]<br><strong><strong>Exemplo</strong></strong> : localhost, 1433</li><li><strong><strong>Tipo de autenticação</strong></strong> : Login SQL</li><li><strong><strong>Nome de usuário</strong></strong> : [seu nome de usuário do SQL Server] ou sa</li><li><strong><strong>Senha</strong></strong> : [sua senha do SQL Server] ou reallyStrongPwd123</li><li><strong><strong>Nome do banco de dados</strong></strong> : &lt;Default&gt;</li><li><strong><strong><strong><strong>Grupo de servidores</strong></strong> : &lt;</strong>Default<strong>&gt;</strong></strong></li></ul><p>Se você estiver usando uma porta diferente da padrão 1433, clique em Advanced... e insira-a no campo de Port. </p><p>Alternativamente, você pode acrescentá-la ao nome do seu servidor com uma vírgula no meio. </p><p>Por exemplo, se você estiver usando a porta 1400, digite localhost,1400. Agora você pode prosseguir e criar bancos de dados, executar scripts e realizar outras tarefas de gerenciamento do SQL Server. </p><ol><li>Clique em <em>New Query </em>(Nova consulta).</li></ol><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-253.png" class="kg-image" alt="image-253" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/image-253.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/10/image-253.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-253.png 1063w" width="1063" height="739" loading="lazy"></figure><p>2. &nbsp; &nbsp; Digite <strong><strong>SELECT @@VERSION</strong></strong>, e clique em <strong><strong>Run Query</strong> </strong>(Executar consulta).</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-241.png" class="kg-image" alt="image-241" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/image-241.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/10/image-241.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-241.png 1482w" sizes="(min-width: 720px) 720px" width="1482" height="1486" loading="lazy"></figure><p>Você deverá conseguir ver: <em><em>Microsoft SQL Server</em></em> em <em>Results</em>.</p><h2 id="importar-um-banco-de-dados-de-exemplo-para-o-sql-server-usando-o-azure-data-studio"><strong>Importar um banco de dados de exemplo para o SQL Server usando o Azure Data Studio</strong></h2><h3 id="baixar-o-arquivo-de-banco-de-dados-de-exemplo-adventureworks"><strong>Baixar o arquivo de banco de dados de exemplo AdventureWorks</strong></h3><p>Para obter os downloads OLTP do AdventureWorks, acesse este <a href="https://docs.microsoft.com/en-us/sql/samples/adventureworks-install-configure?view=sql-server-ver15">link</a> e escolha qualquer banco de dados de amostra. No meu exemplo, eu escolho <code>AdventureWorks2017.bak</code>. Faremos o upload disso para o <em>S3 Bucket.</em></p><h3 id="copiar-o-arquivo-para-sua-janela-de-encaixe"><strong>Copiar o arquivo para sua janela de encaixe</strong></h3><p>Digite o seguinte comando no terminal seguindo esta sintaxe:</p><pre><code>docker cp &lt;location_of_file&gt; &lt;container_id&gt;:/var/opt/mssql/data</code></pre><p>Deverá ficar assim:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-255.png" class="kg-image" alt="image-255" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/image-255.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/10/image-255.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2023/10/image-255.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-255.png 1680w" sizes="(min-width: 1200px) 1200px" width="1680" height="42" loading="lazy"></figure><p>Se você esqueceu o ID do contêiner, use o comando <code>docker ps</code>.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-258.png" class="kg-image" alt="image-258" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/image-258.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/10/image-258.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2023/10/image-258.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w2400/2023/10/image-258.png 2400w" sizes="(min-width: 1200px) 1200px" width="2828" height="120" loading="lazy"></figure><h3 id="importar-o-banco-de-dados-de-exemplo-no-docker"><strong>Importar o banco de dados de exemplo no Docker</strong></h3><p>Vá para Azure Data Studio e clique em <strong><strong>localhost, 1443</strong></strong> e escolha <strong><strong><em>Restore</em></strong> </strong>(Restaurar).</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-265.png" class="kg-image" alt="image-265" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/image-265.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/10/image-265.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-265.png 1098w" sizes="(min-width: 720px) 720px" width="1098" height="674" loading="lazy"></figure><p>Em seguida, escolha <em><strong>"Backup file"</strong></em> como a opção a partir da qual fazer a restauração. Em seguida, clique no botão azul à direita do caminho do arquivo de backup.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-264.png" class="kg-image" alt="image-264" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/image-264.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/10/image-264.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2023/10/image-264.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-264.png 2000w" sizes="(min-width: 1200px) 1200px" width="2000" height="470" loading="lazy"></figure><p>Procure o arquivo de banco de dados de exemplo. Deve estar localizado em:</p><pre><code class="language-terminal">/var/opt/mssql/data/AdventureWorks2017.bak</code></pre><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-260.png" class="kg-image" alt="image-260" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/image-260.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/10/image-260.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2023/10/image-260.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-260.png 2000w" sizes="(min-width: 1200px) 1200px" width="2000" height="714" loading="lazy"></figure><p>Escolha <strong><strong>Restore</strong></strong>.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-263.png" class="kg-image" alt="image-263" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/image-263.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/10/image-263.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2023/10/image-263.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-263.png 2378w" sizes="(min-width: 1200px) 1200px" width="2378" height="524" loading="lazy"></figure><p>Verifique seu host local, 1443. Ele deve gerar um banco de dados chamado AdventureWorks2017 e conter conteúdo como tabelas e visualizações. Caso contrário, clique com o botão direito em localhost, 1443 e escolha <em>Refresh</em> (Atualizar). Você também pode reiniciar seu aplicativo Azure Data Studio.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-262.png" class="kg-image" alt="image-262" width="550" height="770" loading="lazy"></figure><h3 id="testar-o-banco-de-dados-de-amostra"><strong>Testar o banco de dados de amostra</strong></h3><ol><li>Escolha <strong><strong>AdventureWorks2017</strong></strong> no menu suspenso.</li><li>Escreva uma consulta SQL:</li></ol><pre><code class="language-sql">SELECT * FROM HumanResources.Department;</code></pre><p>3. Clique em <strong><strong>Executar</strong></strong> para executar a consulta.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-266.png" class="kg-image" alt="image-266" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/image-266.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/10/image-266.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-266.png 1408w" sizes="(min-width: 720px) 720px" width="1408" height="208" loading="lazy"></figure><p>Você deve ter uma saída como esta:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-267.png" class="kg-image" alt="image-267" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/image-267.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/10/image-267.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-267.png 1436w" sizes="(min-width: 720px) 720px" width="1436" height="684" loading="lazy"></figure><p>Parabéns! Você conclui o processo!</p><p>Recursos:</p><ul><li><a href="https://database.guide/how-to-install-sql-server-on-a-mac/">Como instalar o SQL Server em um Mac</a> (em inglês)</li></ul><p>Conecte-se com o autor pelo LinkedIn <a href="https://www.linkedin.com/in/clarkngo/">aqui</a>.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-240.png" class="kg-image" alt="image-240" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/image-240.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/10/image-240.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/image-240.png 1486w" sizes="(min-width: 720px) 720px" width="1486" height="696" loading="lazy"></figure> ]]>
                </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>
        
    </channel>
</rss>
