<?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[ Airel Ribeiro e Silva - 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[ Airel Ribeiro e Silva - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/portuguese/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Fri, 26 Jun 2026 04:36:20 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/portuguese/news/author/airel/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Como criar uma aplicação do Vue.js usando componentes de arquivo único sem a CLI ]]>
                </title>
                <description>
                    <![CDATA[ Uma compreensão dos componentes de arquivo único (em inglês, single-file components – SFCs) do Vue e do gerenciador de pacotes do Node (Node Package Manager – NPM) será útil para este artigo. A interface de linha de comando, ou CLI, de um framework é o método preferido para estruturar um ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-criar-uma-aplicacao-do-vue-js-usando-componentes-de-arquivo-unico-sem-a-cli/</link>
                <guid isPermaLink="false">64c977c1529f3305560afeab</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Airel Ribeiro e Silva ]]>
                </dc:creator>
                <pubDate>Tue, 12 Sep 2023 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/1_L2343t5yIriMN69KY6jWEw.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/how-to-create-a-vue-js-app-using-single-file-components-without-the-cli-7e73e5b8244f/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to create a Vue.js app using Single-File Components, without the CLI.</a>
      </p><p><em>Uma compreensão dos componentes de arquivo único (em inglês, single-file components – SFCs) do Vue e do gerenciador de pacotes do Node (Node Package Manager – NPM) será útil para este artigo.</em></p><p>A interface de linha de comando, ou CLI, de um framework é o método preferido para estruturar um projeto. Ela fornece um ponto de partida para arquivos, pastas e configurações. Essa estrutura básica também inclui um processo de desenvolvimento e um de construção (do inglês, <em>build</em>). O processo de desenvolvimento permite ver as atualizações à medida que você edita o projeto. Já o processo de construção cria a versão final dos arquivos a serem utilizados em produção.</p><p>A instalação e a execução do Vue.js ("Vue") podem ser feitas através de uma tag de script que aponta para a rede de entrega de conteúdo (do inglês, <em>content delivery network</em>, ou <em>CDN</em>) do Vue. Nenhum processo de construção ou de desenvolvimento é necessário neste caso. No entanto, se você utilizar componentes de arquivo único (os <em>single-file components</em> - ou <em>SFCs</em>), será necessário converter esses arquivos em algo que o navegador possa entender. Os arquivos precisam ser convertidos em linguagem de hipertexto (HTML), estilo em cascata (CSS) e JavaScript (JS). Nesse caso, é necessário utilizar os processos de desenvolvimento e de construção.</p><p>Em vez de depender da CLI do Vue para criar a estrutura do projeto e fornecer um processo de desenvolvimento e de construção, construiremos um projeto do zero. Criaremos nossos próprios processos de desenvolvimento e de construção usando o Webpack.</p><h4 id="o-que-o-webpack"><strong>O que é<strong> </strong>o <strong>Webpack?</strong></strong></h4><p>O Webpack é um <em>module bundler</em> (empacotador de módulos, em português). Ele combina o código de vários arquivos em um só. Antes do Webpack, a pessoa usuária precisava incluir uma tag de script para cada arquivo JavaScript. Embora os navegadores estejam gradualmente oferecendo suporte a módulos do ES6, o Webpack continua sendo a maneira preferida de construir um código modular.</p><p>Além de ser um "<em>module bundler</em>", o Webpack também pode transformar o código. Por exemplo, ele pode pegar código JavaScript moderno (do ECMAScript 6 e posteriores) e convertê-lo em ECMAScript 5. Enquanto o Webpack <em>empacota</em> o código em si, ele transforma o código usando <em>loaders</em> e <em>plug-ins</em>. Pense nos <em>loaders</em> e <em>plug-ins</em> como complementos para o Webpack.</p><h4 id="webpack-e-vue"><strong><strong>Webpack </strong>e<strong> Vue</strong></strong></h4><p>Os componentes de arquivo único nos permitem construir um componente inteiro (estrutura, estilo e função) em um único arquivo. Além disso, a maioria dos editores de código fornece destaque de sintaxe e verificação de código para esses SFCs.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/1_anBAz9QzClNtmAxp4ujdGA.png" class="kg-image" alt="1_anBAz9QzClNtmAxp4ujdGA" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/09/1_anBAz9QzClNtmAxp4ujdGA.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/09/1_anBAz9QzClNtmAxp4ujdGA.png 800w" width="800" height="879" loading="lazy"><figcaption><a href="https://vuejs.org/guide/scaling-up/sfc.html">Componente de arquivo único do Vue</a>: perceba a extensão,<em><em> .vue</em> </em>(documentação em inglês).</figcaption></figure><p><em>Observe que o arquivo termina com .vue. O navegador não sabe o que fazer com essa extensão. O Webpack, por meio do uso de "loaders" e de "plug-ins", transforma esse arquivo em HTML, CSS e JS que o navegador pode entender e consumir.</em></p><h3 id="o-projeto-criar-uma-aplica-o-do-vue-do-tipo-hello-world-usando-componentes-de-arquivo-nico"><strong>O projeto<strong>: </strong>criar uma aplicação do Vue do tipo "Hello World" usando componentes de arquivo único</strong></h3><h3 id="primeiro-passo-criar-a-estrutura-do-projeto">Primeiro passo: criar a estrutura do projeto</h3><p>O projeto básico do Vue incluirá um arquivo HTML, um arquivo JavaScript e um arquivo Vue (o arquivo com a extensão .<em>vue</em>). Vamos colocar esses arquivos em uma <strong>pasta<strong> </strong>chamada<strong> </strong></strong><code>src</code><strong><strong>.</strong> </strong>A pasta <code>src</code> nos ajudará a separar o código que estamos escrevendo do código que o Webpack criará posteriormente.</p><p>Como estaremos usando o Webpack, precisamos de <strong>um arquivo de configuração do Webpack.</strong></p><p>Além disso, usaremos um compilador chamado <strong>Babel</strong>. O Babel nos permite escrever código em ES6 que será compilado para ES5. O Babel é um dos "recursos adicionais" para o Webpack. <strong>Ele também precisa de um arquivo de configuração.</strong></p><p>Por fim, como estamos usando o NPM, também teremos uma pasta <strong>node_modules</strong> e um arquivo <strong>package.json</strong>. Eles serão criados automaticamente quando inicializarmos nosso projeto como um projeto do NPM e quando começarmos a instalar nossas dependências.</p><p>Para começar, crie uma pasta chamada <code>hello-world</code>. No terminal, vá para esse diretório e execute o comando <code>npm init</code>. Siga as instruções na tela para criar o projeto. Em seguida, crie as outras pastas (exceto a pasta <code>node_modules</code>)<em><em> </em></em>conforme descrito acima. A estrutura do seu projeto deve ficar assim:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/1_jLNggGBoQ6A6xnqVyltFEA.png" class="kg-image" alt="1_jLNggGBoQ6A6xnqVyltFEA" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/09/1_jLNggGBoQ6A6xnqVyltFEA.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/09/1_jLNggGBoQ6A6xnqVyltFEA.png 660w" width="660" height="438" loading="lazy"><figcaption>A estrutura de projeto com SFCs do Vue mais simples.</figcaption></figure><h4 id="segundo-passo-instale-as-depend-ncias"><strong>Segundo passo<strong>: </strong>instale as dependências</strong></h4><p>Aqui está um resumo rápido das dependências que estamos usando:</p><p><strong><strong>vue</strong></strong>: o <em>framework</em> do JavaScript </p><p><strong><strong>vue-loader </strong></strong>e <strong><strong>vue-template-compiler</strong></strong>: usados para converter nossos arquivos do Vue em JavaScript.</p><p><strong><strong>webpack</strong></strong>: a ferramenta que nos permitirá transformar o nosso código e agrupá-lo em um único arquivo.</p><p><strong><strong>webpack-cli:</strong></strong> necessário para executar os comandos do Webpack.</p><p><strong><strong>webpack-dev-server</strong></strong>: embora não seja necessário para nosso pequeno projeto (já que não faremos nenhuma solicitação HTTP), ainda "serviremos" nosso projeto a partir de um servidor de desenvolvimento.</p><p><strong><strong>babel-loader</strong></strong>: transforma nosso código ES6 em ES5 (ele precisará da ajuda das duas próximas dependências).</p><p><strong><strong>@babel/core </strong>e<strong> @babel/preset-env</strong></strong>: o Babel por si só não fará nada com o seu código. Esses dois "<em>add-ons</em>" nos permitirão transformar nosso código ES6 em código ES5.</p><p><strong><strong>css-loader: </strong></strong>pega o CSS que escrevemos em nossos arquivos <code>.vue</code><em><em> </em></em>ou qualquer CSS que possamos importar em nossos arquivos JavaScript e resolve o caminho para esses arquivos. Em outras palavras, ele descobre onde está o CSS. Este é outro <em>loader</em> que, por si só, não fará muito. Precisamos do próximo <em>loader</em> para fazer algo com o CSS.</p><p><strong><strong>vue-style-loader</strong></strong>: pega o CSS que obtivemos do nosso css-loader e o injeta em nosso arquivo HTML. Isso criará e injetará uma tag de estilo no cabeçalho de nosso documento HTML.</p><p><strong><strong>html-webpack-plugin</strong></strong>: pega nosso <em>index.html</em> e injeta nosso arquivo JavaScript agrupado no cabeçalho. Em seguida, copia este arquivo para a pasta <code>dist</code>.</p><p><strong><strong>rimraf</strong></strong>: permite-nos, a partir da linha de comando, excluir arquivos. Isso será útil quando construirmos nosso projeto várias vezes. Usaremos isso para excluir quaisquer compilações antigas.</p><p>Vamos instalar essas dependências agora. No terminal, execute o seguinte comando:</p><pre><code class="language-bash">npm install vue vue-loader vue-template-compiler webpack webpack-cli webpack-dev-server babel-loader @babel/core @babel/preset-env css-loader vue-style-loader html-webpack-plugin rimraf -D</code></pre><p><strong><em>Observação</em><strong><em><em>: </em></em></strong></strong><em>o "-D" no final de cada dependência marca cada uma delas como uma dependência de desenvolvimento em nosso package.json. Estamos agrupando todas as dependências em um único arquivo. Portanto, para nosso pequeno projeto, não temos dependências de produção.</em></p><h4 id="terceiro-passo-criar-os-arquivos-exceto-o-arquivo-de-configura-o-do-webpack-"><strong>Terceiro passo<strong>: </strong>criar os arquivos<strong> (</strong>e</strong>xceto o arquivo de configuração do Webpack<strong><strong>)</strong></strong></h4><figure class="kg-card kg-code-card"><pre><code class="language-js">&lt;template&gt;
  &lt;div id="app"&gt;
    {{ message }}
  &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
export default {
  data() {
    return {
      message: 'Hello World',
    };
  },
};
&lt;/script&gt;

&lt;style&gt;
#app {
  font-size: 18px;
  font-family: 'Roboto', sans-serif;
  color: blue;
}
&lt;/style&gt;</code></pre><figcaption>a1-App.vue</figcaption></figure><figure class="kg-card kg-code-card"><pre><code class="language-html">&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;Vue Hello World&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div id="app"&gt;&lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;</code></pre><figcaption>a1-index.html</figcaption></figure><figure class="kg-card kg-code-card"><pre><code class="language-js">import Vue from 'vue';
import App from './App.vue';

new Vue({
  el: '#app',
  render: h =&gt; h(App),
});</code></pre><figcaption>a1-main.js</figcaption></figure><figure class="kg-card kg-code-card"><pre><code class="language-js">module.exports = {
  presets: ['@babel/preset-env'],
}</code></pre><figcaption>a1-babelrc.js</figcaption></figure><p>Até esse ponto, nada deve parecer muito estranho. Mantive cada arquivo muito básico. Adicionei apenas CSS e JS mínimos para ver nosso fluxo de trabalho em ação.</p><h4 id="quarto-passo-instruir-o-webpack-sobre-o-que-fazer"><strong>Quarto passo<strong>: </strong>instruir o Webpack sobre o que fazer</strong></h4><p>Toda a configuração necessária para o Webpack está presente. Precisamos fazer duas coisas finais: dizer ao Webpack o que fazer e executar o Webpack.</p><p>Abaixo está o arquivo de configuração do Webpack (<code>webpack.config.js</code>). Crie o arquivo no diretório raiz do projeto. Vamos discutir linha por linha o que está ocorrendo:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">const HtmlWebpackPlugin = require('html-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');

module.exports = {
  entry: './src/main.js',
  module: {
    rules: [
      { test: /\.js$/, use: 'babel-loader' },
      { test: /\.vue$/, use: 'vue-loader' },
      { test: /\.css$/, use: ['vue-style-loader', 'css-loader']},
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
    }),
    new VueLoaderPlugin(),
  ]
};</code></pre><figcaption>a1-webpack.config.js</figcaption></figure><p><strong><strong>Lin</strong>ha<strong>s 1 </strong>e<strong> 2:</strong></strong> estamos importando os dois <em>plug-ins</em> que usamos abaixo. Observe que nossos <em>loaders</em> normalmente não precisam ser importados, apenas nossos "<em>plug-ins</em>". Em nosso caso, o<em><em> </em></em><code>vue-loader</code> (que usamos na linha 9) também precisa de um <em>plug-in</em> para funcionar (no entanto, o Babel, por exemplo, não precisa).</p><p><strong><strong>Lin</strong>ha<strong> 4:</strong></strong> exportamos nossa configuração como um objeto. Isso nos dá acesso a ele quando executamos os comandos do Webpack.</p><p><strong><strong>Lin</strong>ha<strong> 5: </strong></strong>este é o nosso módulo de entrada (<em>entry</em>). O Webpack precisa de um ponto de partida. Ele procura em nosso arquivo <code>main.js</code> e começa a percorrer nosso código a partir desse ponto.</p><p><strong><strong>Lin</strong>has<strong> 6 </strong>e<strong> 7:</strong></strong> este é o objeto módulo. Aqui, passamos principalmente um <em>array</em> de regras. Cada regra informa ao Webpack como lidar com determinados arquivos. Então, enquanto o Webpack usa o ponto de entrada <code>main.js</code> para começar a percorrer nosso código, ele usa essas regras para transformar nosso código.</p><p><strong><strong>Li</strong>nha<strong> 8 (</strong>regra<strong>):</strong></strong> essa regra instrui o Webpack a usar o <code>babel-loader</code> em qualquer arquivo que termine com <code>.js</code><em><em>. </em></em>Lembre-se de que o Babel transformará o ES6 e versões posteriores em ES5.</p><p><strong><strong>Lin</strong>ha<strong> 9 (r</strong>egra<strong>):</strong></strong> essa regra instrui o Webpack a usar o <code>vue-loader</code><em><em> </em></em>(e a não esquecer do <em>plug-in </em>associado na linha 17) para transformar nossos arquivos <code>.vue</code> em JavaScript.</p><p><strong><strong>Lin</strong>ha<strong> 10 (r</strong>egra<strong>):</strong></strong> às vezes, queremos passar um arquivo por dois <em>loaders</em>. De maneira contraintuitiva, o Webpack passará o arquivo da direita para a esquerda em vez de da esquerda para a direita. Aqui estamos usando dois <em>loaders</em> e dizendo ao Webpack: "pegue meu CSS do meu arquivo Vue ou de quaisquer arquivos JavaScript (<code>css-loader</code>) e injete-o em meu HTML como uma tag de estilo (<code>vue-style-loader</code>).</p><p><strong><strong>Lin</strong>has<strong> 11 </strong>e<strong> 12:</strong></strong> fecha nosso <em>array</em> de regras e o objeto de módulo.</p><p><strong><strong>Lin</strong>ha<strong> 13: </strong></strong>cria um <em>array </em>de <em>plug-ins</em>. Aqui adicionaremos os dois <em>plug-ins</em> que precisamos.</p><p><strong><strong>Lin</strong>has<strong>: 14 </strong>a <strong>16 (plug</strong>-<strong>in):</strong></strong> o <code>HtmlWebpackPlugin</code> pega a localização do nosso arquivo "index.html" e adiciona nosso arquivo JavaScript agrupado a ele através de uma tag de script. Esse plug-in também copiará o arquivo HTML para nossa pasta de distribuição (<em>dist</em>) quando construirmos nosso projeto.</p><p><strong><strong>Lin</strong>ha<strong> 17 (plug</strong>-<strong>in): </strong></strong>o <code>VueLoaderPlugin</code> trabalha com nosso <code>vue-loader</code> para analisar nossos arquivos <code>.vue</code>.</p><p><strong><strong>Lin</strong>ha<strong> 18:</strong></strong> fecha o array de <em>plug-ins</em>.</p><p><strong><strong>Lin</strong>ha<strong> 19:</strong></strong> fecha o objeto do Webpack que estamos exportando.</p><h4 id="quinto-passo-configurar-o-arquivo-package-json-para-que-possamos-executar-o-webpack"><strong>Quinto passo<strong>: </strong></strong>configurar o arquivo package.json para que possamos executar o Webpack</h4><p>Nossa configuração está completa, agora queremos ver nossa aplicação. Idealmente, à medida que fazemos alterações em nossa aplicação, o navegador deve ser atualizado automaticamente. Isso é possível com o <code>webpack-dev-server</code>.</p><p>Exclua o script de <code>test</code> em nosso arquivo <code>package.json</code> e substitua-o por um script para servir nossa aplicação:</p><figure class="kg-card kg-code-card"><pre><code class="language-json">
{
  "name": "hello-world",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "scripts": {
    "serve": "webpack-dev-server --mode development"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.1.6",
    "@babel/preset-env": "^7.1.6",
    "babel-loader": "^8.0.4",
    "css-loader": "^1.0.1",
    "html-webpack-plugin": "^3.2.0",
    "rimraf": "^2.6.2",
    "vue": "^2.5.17",
    "vue-loader": "^15.4.2",
    "vue-style-loader": "^4.1.2",
    "vue-template-compiler": "^2.5.17",
    "webpack": "^4.26.0",
    "webpack-cli": "^3.1.2",
    "webpack-dev-server": "^3.1.10"
  },
  "dependencies": {}
}</code></pre><figcaption>a1-package.json</figcaption></figure><p>O nome desse comando é de sua escolha. Eu escolhi chamá-lo de <code>serve</code> já que estaremos <em>servindo</em> nossa aplicação.</p><p>A partir de nosso terminal ou linha de comando, podemos executar <code>npm run serve</code> e isso, por sua vez, executará <code>webpack-dev-server --mode development</code>.</p><p><em>O <code>--mode development</code> é o que chamamos de flag ou opção. Ainda não falamos sobre isso, mas, essencialmente, instrui o Webpack de que você está no modo de desenvolvimento. Também podemos passar <code>--mode production</code>, que é algo que faremos quando construirmos nosso projeto. Essas opções não são necessariamente obrigatórias para que o Webpack funcione. Sem elas, você receberá uma mensagem de aviso dizendo para fornecer um modo ao executar o Webpack.</em></p><p><em>Eu digo "necessariamente obrigatórias" porque o Webpack minimizará nosso código no modo de produção, mas não no modo de desenvolvimento. Portanto, não pense que esses comandos não fazem nada – eles fazem.</em></p><p>Vamos executar <code>npm run serve</code> e ver o que acontece.</p><p>Quando executamos <code>npm run serve</code>, obtemos algumas informações em nosso terminal. Se tudo correr bem, o que temos será o seguinte:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/1_UNoqxigEpgvVZRjs2VqxTA.png" class="kg-image" alt="1_UNoqxigEpgvVZRjs2VqxTA" width="493" height="85" loading="lazy"></figure><p>Se rolarmos um pouco para cima, veremos isto:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/1_ye4_gCeGPXcwgPcGUQf_rg.png" class="kg-image" alt="1_ye4_gCeGPXcwgPcGUQf_rg" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/09/1_ye4_gCeGPXcwgPcGUQf_rg.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/09/1_ye4_gCeGPXcwgPcGUQf_rg.png 800w" sizes="(min-width: 720px) 720px" width="800" height="112" loading="lazy"></figure><p>Acesse seu navegador em <code>http://localhost:8080</code>. Você verá sua mensagem "Hello World" em azul na fonte Roboto.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/1_kKYxmKJ_rTBzT7rOvjZtgg.png" class="kg-image" alt="1_kKYxmKJ_rTBzT7rOvjZtgg" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/09/1_kKYxmKJ_rTBzT7rOvjZtgg.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/09/1_kKYxmKJ_rTBzT7rOvjZtgg.png 800w" sizes="(min-width: 720px) 720px" width="800" height="129" loading="lazy"></figure><p>Agora, vamos atualizar o projeto e mudar a mensagem para <code>Hello Universe</code>. Observe que a página é atualizada automaticamente. Isso é ótimo, não é? Você consegue pensar em uma desvantagem?</p><p>Vamos mudar um pouco a aplicação e incluir um campo de entrada (<em>input</em>) ao qual vincularemos uma variável (usando <code>v-model</code>). Vamos exibir o conteúdo da variável em uma tag <code>&lt;h2&gt;</code> abaixo do campo de entrada. Também atualizei a seção de estilo para estilizar a mensagem. Nosso arquivo <code>App.vue</code><em><em> </em></em>deve ficar assim:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">&lt;template&gt;
  &lt;div id="app"&gt;
    &lt;input
      v-model="message"
      type="text"&gt;
      &lt;h2 class="message"&gt;{{ message }}&lt;/h2&gt;
  &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
export default {
  data() {
    return {
      message: 'Hello world!',
    };
  },
};
&lt;/script&gt;

&lt;style&gt;
.message {
  font-size: 18px;
  font-family: 'Roboto', sans-serif;
  color: blue;
}
&lt;/style&gt;</code></pre><figcaption>a11-App.vue</figcaption></figure><p>Quando servimos nossa aplicação, teremos um campo de entrada com a mensagem <code>Hello World</code> abaixo dele. O campo de entrada está vinculado à variável <code>message</code>. Então, conforme digitamos, alteramos o conteúdo da tag <code>&lt;h2&gt;</code>. Vá em frente, digite no campo de entrada para mudar o conteúdo da tag <code>&lt;h2&gt;</code>.</p><p>Agora, volte para o seu editor e, abaixo da tag <code>&lt;h2&gt;</code>, adicione o seguinte:</p><p><code>&lt;h3&gt;</code>Some Other Message<code>&lt;/h3&gt;</code> (Alguma outra mensagem)</p><p>Salve seu arquivo <code>App.vue</code> e observe o que acontece.</p><p>O <code>h2</code> que acabamos de atualizar digitando no campo de entrada voltou para <code>Hello World</code>. Isso acontece porque o navegador atualiza de fato a página e recarrega a tag de script e o conteúdo da página. Em outras palavras, não conseguimos manter o estado de nossa aplicação. Isso pode não parecer um grande problema, mas à medida que você testa sua aplicação e adiciona dados a ela, será frustrante se seu aplicativo "reiniciar" toda vez. Felizmente, o Webpack nos oferece uma solução chamada <em>Hot Module Replacement (em português, algo como "substituição rápida dos módulos")</em>.</p><p>O <em>Hot Module Replacement</em> é um <em>plug-in</em> fornecido pelo próprio Webpack. Até esse ponto, não usamos diretamente o objeto do Webpack em nosso arquivo de configuração. No entanto, agora vamos importar o Webpack para que possamos acessar o <em>plug-in</em>.</p><p>Além do <em>plug-in</em>, passaremos uma opção adicional para o Webpack, a opção <code>devServer</code>. Nessa opção, definiremos <code>hot</code> como <code>true</code>. Também faremos uma atualização opcional em nosso fluxo de trabalho de construção: vamos abrir automaticamente a janela do navegador quando executarmos <code>npm run serve</code>. Fazemos isso definindo <code>open</code> como <code>true</code> também dentro da opção <code>devServer</code>.</p><figure class="kg-card kg-code-card"><pre><code class="language-js">const HtmlWebpackPlugin = require('html-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const webpack = require('webpack');

module.exports = {
  entry: './src/main.js',
  module: {
    rules: [
      { test: /\.js$/, use: 'babel-loader' },
      { test: /\.vue$/, use: 'vue-loader' },
      { test: /\.css$/, use: ['vue-style-loader', 'css-loader']},
    ]
  },
  devServer: {
    open: true,
    hot: true,
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
    }),
    new VueLoaderPlugin(),
    new webpack.HotModuleReplacementPlugin(),
  ]
};</code></pre><figcaption>a11-webpack.config.js</figcaption></figure><p>Observe que importamos o Webpack para que pudéssemos acessar o <code>hotModuleReplacementPlugin</code>. Adicionamos esse <em>plug-in</em> ao <em>array</em> <code>plugins</code> e, em seguida, informamos ao Webpack para usá-lo com <code>hot: true</code>. Abrimos automaticamente a janela do navegador quando servimos a aplicação com <code>open: true</code>.</p><p>Execute <code>npm run serve</code>:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/1_59LVTDT3pEk3RzQ7dodmvw.png" class="kg-image" alt="1_59LVTDT3pEk3RzQ7dodmvw" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/09/1_59LVTDT3pEk3RzQ7dodmvw.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/09/1_59LVTDT3pEk3RzQ7dodmvw.png 800w" sizes="(min-width: 720px) 720px" width="800" height="161" loading="lazy"></figure><p>A janela do navegador deve abrir. Se você abrir as ferramentas de desenvolvedor, deve notar uma pequena alteração na saída. Agora, ela informa que o "<em>hot module replacement</em>" está habilitado. Digite no campo de entrada para alterar o conteúdo da tag <code>&lt;h2&gt;</code>. Em seguida, altere a tag <code>&lt;h3&gt;</code> para ler: <code>One More Message</code> (Mais uma mensagem).</p><p>Salve seu arquivo e observe o que acontece.</p><p>O navegador não é recarregado, mas nossa alteração na tag <code>&lt;h3&gt;</code> é refletida! A mensagem que digitamos no campo de entrada permanece, mas a <code>h3</code> é atualizada. Isso permite que nossa aplicação mantenha seu estado enquanto a editamos.</p><h4 id="sexto-passo-criar-nosso-projeto"><strong>Sexto passo<strong>: </strong></strong>criar nosso projeto</h4><p>Até agora, servimos nossa aplicação. O que podemos fazer, porém, quisermos construí-la para poder distribuí-la?</p><p>Se você percebeu, quando servimos nossa aplicação, nenhum arquivo é criado. O Webpack cria uma versão desses arquivos que só existe na memória temporária. Se quisermos distribuir nossa aplicação "Hello World" para nosso <em>client</em>, precisamos fazer a <em>build</em> (construir) do projeto.</p><p>Isso é muito simples. Assim como antes, criaremos um script em nosso arquivo <em>package.json</em> para dizer ao Webpack para construir nosso projeto. Usaremos <code>webpack</code> como o comando em vez de <code>webpack-dev-server</code>. Também passaremos a opção <code>--mode production</code>.</p><p>Usaremos o pacote <code>rimraf</code> primeiro para excluir quaisquer <em>builds </em>anteriores que possamos ter. Faremos isso simplesmente com o comando <code>rimraf dist</code>.</p><p><em><code>dist</code> é a pasta que o Webpack criará automaticamente quando construir nosso projeto. “Dist” é uma abreviação de "distribution", ou seja, estamos "distribuindo" o código de nossa aplicação.</em></p><p>O comando <code>rimraf dist</code> está instruindo o pacote<em><em> </em></em><code>rimraf</code> a excluir o diretório <code>dist</code> <strong>Certifique-se de não executar </strong><code>rimraf src</code><strong> por acidente!</strong></p><p><em>O Webpack também oferece um plug-in que realiza esse processo de limpeza, chamado <code>clean-webpack-plugin</code>. Eu escolhi usar <code>dist</code> como um modo alternativo.</em></p><p>Nosso arquivo <em>package.json</em> deve ficar assim:</p><figure class="kg-card kg-code-card"><pre><code class="language-json">{
  "name": "hello-world",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "scripts": {
    "clean": "rimraf dist",
    "build": "npm run clean &amp;&amp; webpack --mode production",
    "serve": "webpack-dev-server --mode development"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.1.6",
    "@babel/preset-env": "^7.1.6",
    "babel-loader": "^8.0.4",
    "css-loader": "^1.0.1",
    "html-webpack-plugin": "^3.2.0",
    "rimraf": "^2.6.2",
    "vue": "^2.5.17",
    "vue-loader": "^15.4.2",
    "vue-style-loader": "^4.1.2",
    "vue-template-compiler": "^2.5.17",
    "webpack": "^4.26.0",
    "webpack-cli": "^3.1.2",
    "webpack-dev-server": "^3.1.10"
  },
  "dependencies": {}
}</code></pre><figcaption>a11-package.json</figcaption></figure><p>Existem três coisas a serem observadas:</p><ol><li>Criei um script separado chamado <code>clean</code> para que possamos executá-lo independentemente do script <em>build</em>.</li><li><code>npm run build</code> chamará o script independente <code>clean</code> que criamos.</li><li>Eu usei o operador <code>&amp;&amp;</code> entre <code>npm run clean</code> e <code>webpack</code>. Essa instrução diz: "execute <code>npm run clean</code> primeiro, <em>só então</em> execute <code>webpack</code>".</li></ol><p>Vamos executar o projeto.</p><p><code>npm run build</code></p><p>O Webpack criará um diretório <code>dist</code> e nosso código estará dentro dele. Como nosso código não faz solicitações HTTP, podemos simplesmente abrir nosso arquivo <code>index.html</code> no navegador e ele funcionará conforme o esperado.</p><p><em>Se tivéssemos um código fazendo solicitações HTTP, encontraríamos alguns erros de origem cruzada ao fazer essas solicitações. Precisaríamos executar esse projeto a partir de um servidor para que funcionasse.</em></p><p>Vamos examinar o <code>index.html</code> que o Webpack criou no navegador e no editor de código.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/1_Y0hwAs2CRmCuBrn7h1pFUw.png" class="kg-image" alt="1_Y0hwAs2CRmCuBrn7h1pFUw" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/09/1_Y0hwAs2CRmCuBrn7h1pFUw.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/09/1_Y0hwAs2CRmCuBrn7h1pFUw.png 800w" sizes="(min-width: 720px) 720px" width="800" height="128" loading="lazy"><figcaption>R</figcaption></figure><p>Se abrirmos no editor ou olharmos o código-fonte nas ferramentas de desenvolvimento, veremos que o Webpack injetou a tag de script. No editor, porém, não veremos os estilos porque a tag de estilo é injetada dinamicamente em tempo de execução com JavaScript! </p><p>Perceba, também, que nossas informações no console do desenvolvedor já não estão presentes. Isso ocorre porque passamos a <em>flag </em><code>--production</code> para o Webpack.</p><h2 id="conclus-o">Conclusão</h2><p>Entender o processo de construção por trás dos <em>frameworks </em>que você utiliza ajudará você a compreender melhor o próprio <em>framework</em>. Então, reserve um tempo para tentar construir um projeto em Angular, React, ou outro projeto em Vue, sem utilizar as respectivas interfaces de linha de comando (CLIs), ou apenas crie um site básico de três arquivos (index.html, styles.css e app.js), mas utilize o Webpack para servir e executar uma versão de produção.</p><p>Agradeço pela leitura!</p><p>Woz</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como atualizar props em um componente do React – sim, isso é possível ]]>
                </title>
                <description>
                    <![CDATA[ Escrito por: Dheeraj DeeKay Se você leu a documentação oficial do React (e você deveria, já que é um recurso incrível disponibilizado pela equipe do React), você deve ter notado essas linhas: > Independente se você declarar um componente como uma função ou uma classe [https://pt-br.reactjs.org/docs/components-and-props.html#function-and-class-components] , ele nunca deve ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-atualizar-props-em-um-componente-do-react-sim-isso-e-possivel/</link>
                <guid isPermaLink="false">638e7367d7295905e9349c6d</guid>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Airel Ribeiro e Silva ]]>
                </dc:creator>
                <pubDate>Mon, 09 Jan 2023 04:19:25 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/01/1_Rzaf_TyulUee7xEdDs3bRw.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-update-a-components-prop-in-react-js-oh-yes-it-s-possible-f9d26f1c4c6d/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to update a component’s prop in ReactJS — oh yes, it’s possible</a>
      </p><p>Escrito por: Dheeraj DeeKay</p><p>Se você leu a documentação oficial do React (e você deveria, já que é um recurso incrível disponibilizado pela equipe do React), você deve ter notado essas linhas:</p><blockquote><a href="https://pt-br.reactjs.org/docs/components-and-props.html#function-and-class-components">Independente se você declarar um componente </a><a href="https://pt-br.reactjs.org/docs/components-and-props.html#function-and-class-components">como uma função ou uma classe</a>, ele nunca deve modificar suas próprias props.<br>React é bastante flexível mas tem uma única regra estrita: <br><strong>Todos os componentes React tem que agir como funções puras em relação às suas props.</strong></blockquote><p>Props nunca devem ser atualizadas. Nós devemos usá-las como são recebidas. Parece rígido, certo? O React, porém, tem seus motivos para ter essa regra e eu estou bastante convencido pelo raciocínio por trás disso. A única exceção entretanto, é que existem situações em que podemos precisar iniciar a atualização de uma prop. Em breve, saberemos como fazer isso.</p><p>Considere a seguinte linha de código de um componente pai:</p><p><code>&lt;MyChild childName={this.state.parentName} /&gt;</code></p><p>Essa é uma linha simples com a qual toda pessoa desenvolvedora em React está familiarizada. Você está chamando seu componente filho. Enquanto faz isso, você também está passando o estado do componente pai (<code>parentName</code>) para o filho. No componente filho, esse estado será acessado como <code>this.props.childName</code>. É isso.</p><p>Agora, se houver a necessidade de qualquer alteração de nome, <code>parentName</code> será alterado no componente pai e essa alteração automaticamente será comunicada ao filho, como é comum no comportamento do React. Essa configuração vai funcionar na maior parte dos cenários.</p><p>Entretanto, o que ocorre se você precisar atualizar a prop de um componente filho, mas a informação da alteração necessária e o disparador para realizá-la só é conhecido por esse componente filho? Considerando os caminhos do React, os dados apenas podem transitar de cima para baixo, do pai para o filho. Assim, como podemos comunicar ao componente pai que a prop precisa ser alterada?</p><p>Bem, embora isso seja contrário ao padrão e não recomendado, as pessoas que desenvolveram a linguagem pensaram nisso. Surpresa!</p><p>Podemos fazer isso usando <code>callbacks</code>. Eu sei, sem surpresas até aqui! Elas parecem ser úteis para todos os problemas que tivemos até agora. Está certo, mas como?</p><p>Imagine se a chamada do componente filho acima fosse modificada da seguinte maneira:</p><p><code>&lt;MyChild childName={this.state.parentName} onNameChange={this.onChange}/&gt;</code></p><p>Agora, além de uma prop <code>childName</code>, nosso componente filho também possui um evento exposto chamado <code>onNameChange</code>. Essa é a forma de resolver o problema. Nosso componente filho fez sua parte. Agora, o componente pai deve fazer o que for necessário. Isso não é motivo de preocupação. Tudo que ele precisa fazer é definir uma função <code>onChange</code>, da seguinte forma:</p><pre><code>function onChange(newName) {this.setState({parentName:newName });}</code></pre><p>É isso. Agora, sempre que quisermos atualizar a prop <code>parentName</code> no componente filho, tudo que precisamos fazer é chamar <code>this.props.onNameChange('My new name')</code> e pronto! Você terá o que deseja. Tudo resolvido. Espero que tenha sido fácil de entender. </p><p><em><strong>Uma última coisa</strong><em><strong><strong>.</strong></strong></em></em></p><p>O React argumenta contra esse método e eles estão certos sobre isso, afinal, vai contra o padrão. Então, sempre que você encontrar uma situação como essa, verifique se é possível subir seu state ou se há uma maneira de dividir seu componente em partes. Isso pode parecer um pouco tedioso, mas saiba que é o modo ideal de se utilizar o React!</p><p>Boa programação para você!</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ É por isso que precisamos vincular manipuladores de eventos quando usamos componentes de classe em React ]]>
                </title>
                <description>
                    <![CDATA[ Enquanto trabalhava com React, você provavelmente encontrou componentes controlados e manipuladores de eventos. Ao usar esses métodos, precisamos vinculá-los à instância dos componentes utilizando .bind() no construtor do nosso componente customizado. class Foo extends React.Component{   constructor( props ){     super( props );    ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/e-por-isso-que-precisamos-vincular-manipuladores-de-eventos-quando-usamos-componentes-de-classe-em-react/</link>
                <guid isPermaLink="false">633d86fcffecac05daeb777c</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Airel Ribeiro e Silva ]]>
                </dc:creator>
                <pubDate>Wed, 04 Jan 2023 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/11/1_kdZr8L9pUOgosVNWqMSmlQ.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/this-is-why-we-need-to-bind-event-handlers-in-class-components-in-react-f7ea1a6f93eb/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">This is why we need to bind event handlers in Class Components in React</a>
      </p><p>Enquanto trabalhava com React, você provavelmente encontrou componentes controlados e manipuladores de eventos. Ao usar esses métodos, precisamos vinculá-los à instância dos componentes utilizando <code>.bind()</code> no construtor do nosso componente customizado.</p><pre><code class="language-jsx">class Foo extends React.Component{
  constructor( props ){
    super( props );
    this.handleClick = this.handleClick.bind(this);
  }
  
  handleClick(event){
    // sua lógica de manipulação do evento
  }
  
  render(){
    return (
      &lt;button type="button" 
      onClick={this.handleClick}&gt;
      Clique aqui
      &lt;/button&gt;
    );
  }
}

ReactDOM.render(
  &lt;Foo /&gt;,
  document.getElementById("app")
);</code></pre><p>Neste artigo, vamos descobrir por que precisamos fazer isso.</p><p>Se você ainda não conhece a função do <code>.bind()</code>, eu recomendo que você leia <a href="https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_objects/Function/bind">aqui</a> o que ele faz.</p><h3 id="culpa-do-javascript-n-o-do-react"><strong>Culpa do <strong><strong>JavaScript,</strong></strong> não do <strong><strong>React</strong></strong></strong></h3><p>Bem, colocar a culpa soa um pouco duro. Isso, porém, não é algo que precisemos fazer por causa da maneira como o React funciona ou por causa do JSX. Isso acontece pela forma como o vínculo de <code>this</code> funciona em JavaScript.</p><p>Vejamos o que acontece se não vincularmos o manipulador de evento à instância do componente:</p><pre><code class="language-jsx">class Foo extends React.Component{
  constructor( props ){
    super( props );
  }
    
  handleClick(event){
    console.log(this); // 'this' é undefined
  }
    
  render(){
    return (
      &lt;button type="button" onClick={this.handleClick}&gt;
        Clique aqui
      &lt;/button&gt;
    );
  }
}

ReactDOM.render(
  &lt;Foo /&gt;,
  document.getElementById("app")
);</code></pre><p><br>Ao executar esse código, clique no botão "Clique aqui" e verifique seu console. Você verá &nbsp;<code>undefined</code> impresso no console como valor do <code>this</code> que está dentro do manipulador de eventos. O método <code>handleClick()</code> parece ter <strong>perdido </strong>seu contexto (a instância do componente) ou o valor do <code>this</code>.</p><h3 id="como-funciona-vincular-o-this-em-javascript"><strong>Como<strong><strong> </strong></strong>funciona vincular o "<strong><strong>this</strong></strong>" em<strong><strong> JavaScript</strong></strong></strong></h3><p>Como já mencionei, isso acontece pelo modo como o vínculo do <code>this</code> funciona em JavaScript. Não entrarei em detalhes neste artigo, mas <a href="https://www.freecodecamp.org/news/the-complete-guide-to-this-in-javascript/">aqui</a> tem um ótimo material para entender o funcionamento do vínculo do <code>this</code> em JavaScript (texto em inglês).</p><p>O relevante para nossa discussão aqui é como o valor do <code>this</code> em uma função depende de como essa função é invocada.</p><h4 id="v-nculo-padr-o"><strong>Vínculo padrão</strong></h4><pre><code class="language-js">function display(){
 console.log(this); // esse 'this' aponta para o objeto global
}

display(); </code></pre><p>Esta é uma chamada de função simples. O valor do <code>this</code> no método <code>display()</code>, neste caso, é o objeto window — ou global — no modo não estrito. No modo estrito o valor de <code>this</code> é <code>undefined</code>.</p><h4 id="v-nculo-impl-cito"><strong>Vínculo implícito</strong></h4><pre><code class="language-js">var obj = {
 name: 'Saurabh',
 display: function(){
   console.log(this.name); // esse 'this' aponta para obj
  }
};

obj.display(); // Saurabh </code></pre><p>Quando chamamos a função desse modo — inserida em um objeto — o valor do <code>this</code> no <code>display()</code> faz referência ao <code>obj</code>.</p><p>Quando, no entanto, atribuímos essa referência de função em outra variável e invocamos a função usando essa nova referência de função, obteremos um valor diferente do <code>this</code> no <code>display()</code> .</p><pre><code class="language-js">var name = "uh oh! global";
var outerDisplay = obj.display;
outerDisplay(); // uh oh! global</code></pre><p>No exemplo acima, quando chamamos <code>outerDisplay()</code>, não especificamos o objeto. Essa é uma chamada de função simples sem o objeto proprietário. Nesse caso, o valor do <code>this</code> dentro do <code>display()</code> volta para o <strong>vínculo</strong> <strong>padrão</strong>; ele aponta para o objeto global ou retorna <code>undefined</code>, se a função for chamada usando o modo estrito.</p><p>Isso é aplicável especialmente ao passar essas funções como <strong>callbacks</strong> em outras funções customizadas, funções de bibliotecas externas ou funções integradas ao JavaScript, como <code>setTimeout</code> .</p><p>Considere que a implementação fictícia abaixo é a definição do <code>setTimeout</code> e chame-a.</p><pre><code class="language-js">// Implementação fictícia do setTimeout
function setTimeout(callback, atraso){

   //'atraso' em milissegundos
   callback();
   
}

setTimeout( obj.display, 1000 );</code></pre><p>Podemos ver que, ao chamar <code>setTimeout</code>, o JavaScript atribui internamente <code>obj.display</code> como <code>callback</code> .</p><pre><code class="language-js">callback = obj.display;</code></pre><p>Essa operação de atribuição, como visto anteriormente, faz com que a função <code>display()</code> perca seu contexto. Quando essa função de <em>callback</em> finalmente for chamada dentro de <code>setTimeout</code>, o valor do <code>this</code> dentro do <code>display()</code> volta para o <strong>vínculo</strong> <strong>padrão</strong>.</p><pre><code class="language-js">var name = "uh oh! global";
setTimeout( obj.display, 1000 );

// uh oh! global</code></pre><h4 id="v-nculo-inflex-vel-expl-cito"><strong>Vínculo inflexível explícito</strong></h4><p>Para evitar isso, podemos <strong>vincular</strong> <strong><strong>explici</strong>tamente </strong>o valor de <code>this</code> a uma função usando o método <code>bind()</code>.</p><pre><code class="language-js">var name = "uh oh! global";
obj.display = obj.display.bind(obj); 
var outerDisplay = obj.display;
outerDisplay();

// Saurabh</code></pre><p>Agora, quando chamamos <code>outerDisplay()</code>, o valor de <code>this</code> aponta para o <code>obj</code> que está dentro de <code>display()</code> .</p><p>Ainda que passemos <code>obj.display</code> como uma <em>callback</em>, o valor do <code>this</code> dentro de <code>display()</code> apontará corretamente para <code>obj</code> .</p><h3 id="recriando-o-cen-rio-usando-apenas-javascript"><strong>Recriando o cenário usando apenas J<strong><strong>avaScript</strong></strong></strong></h3><p>No início deste artigo, vimos esse comportamento em nosso componente do React chamado <code>Foo</code> . Se não vinculássemos o manipulador de eventos com <code>this</code> , seu valor dentro dele seria <code>undefined</code>.</p><p>Como expliquei acima, isso acontece pelo modo como o vínculo de <code>this</code> funciona no JavaScript e não está relacionado ao modo como o React funciona. Para visualizar isso, vamos remover o código específico do React e construir um exemplo semelhante com JavaScript puro simulando esse comportamento.</p><pre><code class="language-jsx">class Foo {
  constructor(name){
    this.name = name
  }
  
  display(){
    console.log(this.name);
  }
}

var foo = new Foo('Saurabh');
foo.display(); // Saurabh

// A operação de atribuição a seguir simula uma perda de contexto
// semelhante a que ocorre ao passar o manipulador como callback 
// em um componente do React real
var display = foo.display; 
display(); // TypeError: this is undefined</code></pre><p>Não estamos simulando eventos e manipuladores reais, mas usando um código sinônimo. Conforme observamos no exemplo do componente do React, o valor de <code>this</code> era <code>undefined</code> porque o contexto foi perdido depois de passar o manipulador como <em>callback </em>— sinônimo a uma operação de atribuição. Isso é o que observamos também neste fragmento de código JavaScript que não é do React.</p><p>“Espere um minuto! O valor de <code>this</code> não deveria apontar para o objeto global, considerando que estamos executando isso no modo não estrito e de acordo com as regras de vinculação padrão? ” você poderia perguntar.</p><p><strong>Não<strong>.</strong></strong> O motivo é o seguinte:</p><blockquote>Os corpos das <em><em>declarações </em></em>e <em><em>expressões</em></em> de classe são executados em <a href="https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Strict_mode">modo estrito</a>, ou seja, os métodos constructor, static e prototype; as funções getter e setter são executadas no modo estrito.</blockquote><p>Você pode ler o artigo completo <a href="https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Classes">aqui</a>.</p><p>Então, para evitar o erro, precisamos vincular o valor de <code>this</code> assim:</p><pre><code class="language-jsx">class Foo {
  constructor(name){
    this.name = name
    this.display = this.display.bind(this);
  }
  
  display(){
    console.log(this.name);
  }
}

var foo = new Foo('Saurabh');
foo.display(); // Saurabh

var display = foo.display;
display(); // Saurabh</code></pre><p>Não precisamos fazer isso no construtor. Podemos fazer isso em outro lugar também. Considere o seguinte:</p><pre><code class="language-jsx">class Foo {
  constructor(name){
    this.name = name;
  }
  display(){
    console.log(this.name);
  }
}

var foo = new Foo('Saurabh');
foo.display = foo.display.bind(foo);
foo.display(); // Saurabh

var display = foo.display;
display(); // Saurabh</code></pre><p>O construtor, porém, é realmente o melhor e mais eficiente lugar do código para incluir as instruções de vinculação do manipulador de eventos, considerando que é onde ocorre toda a inicialização.</p><h4 id="por-que-n-o-precisamos-vincular-o-this-nas-arrow-functions"><strong><strong><strong>Por que não precisamos vincular</strong> o<strong> <code>this</code> </strong></strong>nas <em>a<strong><strong>rrow functions</strong></strong></em><strong><strong>?</strong></strong></strong></h4><p>Temos mais duas maneiras de definir manipuladores de eventos dentro de um componente do React.</p><ul><li><strong><a href="https://babeljs.io/docs/en/babel-plugin-proposal-class-properties"><strong>Sintaxe de </strong>c<strong>ampos de </strong>c<strong>lasse</strong>s<strong> </strong>p<strong>úbli</strong>cos<strong> (</strong>e<strong>xperimental)</strong></a></strong> - em inglês</li></ul><pre><code class="language-jsx">class Foo extends React.Component{
  handleClick = () =&gt; {
    console.log(this); 
  }
 
  render(){
    return (
      &lt;button type="button" onClick={this.handleClick}&gt;
        Clique aqui
      &lt;/button&gt;
    );
  }
} 

ReactDOM.render(
  &lt;Foo /&gt;,
  document.getElementById("app")
);</code></pre><ul><li><strong><a href="https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Functions/Arrow_functions"><strong>Arrow function </strong>em<strong> callback</strong></a></strong></li></ul><pre><code class="language-jsx">class Foo extends React.Component{
 handleClick(event){
    console.log(this);
  }
 
  render(){
    return (
      &lt;button type="button" onClick={(e) =&gt; this.handleClick(e)}&gt;
        Clique aqui
      &lt;/button&gt;
    );
  }
}

ReactDOM.render(
  &lt;Foo /&gt;,
  document.getElementById("app")
);</code></pre><p>Ambos usam <em>arrow functions</em>, introduzidas no ES6. Quando optamos por essa alternativa, nosso manipulador de eventos já está automaticamente vinculado à instância do componente. Então, não precisamos fazer o vínculo no construtor.</p><p>O motivo disso é que, no caso das <em>arrow functions</em>, o <code>this</code> é vinculado <strong>de modo lexical</strong>. Isso significa que o contexto da função que o envolve – ou o escopo global – é usado como valor do <code>this</code>.</p><p>No exemplo da sintaxe dos campos públicos da classe, a <em>arrow function </em>está fechada dentro da classe <code>Foo</code> &nbsp;— ou função construtora. Assim, o contexto é a instância do componente, que é o que queremos.</p><p>No exemplo da <em>arrow function</em> como <em>callback</em>, a <em>arrow function</em> está fechada dentro do método <code>render()</code>, que é invocado pelo React no contexto da instância do componente. É por isso que a <em>arrow function</em> também possuirá esse contexto. O valor do <code>this</code> nela apontará corretamente para a instância do componente.</p><p>Para mais detalhes sobre a léxico do vínculo <code>this</code>, confira <a href="https://github.com/getify/You-Dont-Know-JS/blob/master/this%20%26%20object%20prototypes/ch2.md#lexical-this">este excelente recurso</a>.</p><h3 id="para-encurtar-uma-longa-hist-ria"><strong>Para encurtar uma longa história</strong></h3><p>Em componentes de classe do React, quando passamos a referência da função de manipulação de eventos como <em>callback</em>, conforme abaixo</p><pre><code class="language-jsx">&lt;button type="button" onClick={this.handleClick}&gt;Clique aqui&lt;/button&gt;</code></pre><p>o manipulador de eventos perde seu contexto de <strong>vínculo implícito</strong>. Quando o evento ocorre e o manipulador é chamado, o valor do <code>this</code> volta para o <strong>vínculo</strong> <strong>padrão<strong> </strong></strong>e é definido como <code>undefined</code>, visto que as declarações de classe e os métodos protótipos são executados no modo estrito.</p><p>Quando vinculamos o <code>this</code> do manipulador de eventos à instância do componente no construtor, podemos passá-lo como <em>callback </em>sem preocupação com a perda de seu contexto.</p><p><em>Arrow functions</em> estão isentas desse comportamento porque usam <strong>vínculo<strong> lexical</strong></strong> com <code>this</code>, o que as vincula automaticamente ao escopo em que são definidas.</p> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
