{"id":9694,"date":"2020-03-24T17:00:00","date_gmt":"2020-03-24T20:00:00","guid":{"rendered":"https:\/\/geekblogti.wpengine.com\/?p=9694"},"modified":"2024-10-29T16:46:49","modified_gmt":"2024-10-29T19:46:49","slug":"twitter-clone-full-stack-app-parte-2-react-tutorial","status":"publish","type":"post","link":"https:\/\/www.geekhunter.com/pt/blog\/twitter-clone-full-stack-app-parte-2-react-tutorial\/","title":{"rendered":"Twitter Clone full stack app \u2013 Parte 2: React tutorial"},"content":{"rendered":"\r\n<p class=\"wp-block-paragraph\">React tutorial? Deixa comigo! \ud83d\ude00<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Nesta parte 2 da nossa aplica\u00e7\u00e3o full-stack iremos criar um clone do Twitter de ponta a ponta!<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Caso n\u00e3o tenha visto a parte 1, criamos o servidor utilizando<strong><a href=\"https:\/\/www.geekhunter.com\/pt\/blog\/node-js-tutorial-twitter-clone-full-stack-app-parte-1\/\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" Node JS Express (abre numa nova aba)\"> Node JS Express<\/a><\/strong>. Voc\u00ea tamb\u00e9m pode acessar o <strong><a href=\"https:\/\/github.com\/picolloo\/twitter-app\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"c\u00f3digo completo no GitHub (abre numa nova aba)\">c\u00f3digo completo no GitHub<\/a><\/strong>, deste e do artigo anterior.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Voc\u00ea tamb\u00e9m pode fazer apenas a parte 2, clonando a branch <em>server<\/em> do reposit\u00f3rio do Github usando o comando:<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><strong><em><a href=\"https:\/\/github.com\/picolloo\/twitter-app.git\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"git clone --single-branch --branch server  (abre numa nova aba)\">git clone &#8211;single-branch &#8211;branch server <\/a><\/em><\/strong><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Ao final deste React tutorial, teremos uma aplica\u00e7\u00e3o totalmente funcional, seguindo boas pr\u00e1ticas de desenvolvimento de software e utilizando os \u00faltimos <strong><a href=\"https:\/\/www.geekhunter.com\/pt\/blog\/criando-componentes-react-componentes-de-classe-e-funcional-sem-estado\/\">conceitos do React<\/a> <\/strong>como:<\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>JSX;<\/li>\r\n<li>Props;<\/li>\r\n<li>State;<\/li>\r\n<li>Hooks.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Teremos uma interface igual a esta:<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-large\"><img fetchpriority=\"high\" decoding=\"async\" width=\"715\" height=\"808\" class=\"wp-image-9733\" src=\"https:\/\/www.geekhunter.com\/pt\/blog\/wp-content\/uploads\/2020\/03\/projeto-de-desenvolvimento-twitter.png\" alt=\"projeto de desenvolvimento twitter\" srcset=\"https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/projeto-de-desenvolvimento-twitter.png 715w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/projeto-de-desenvolvimento-twitter-133x150.png 133w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/projeto-de-desenvolvimento-twitter-88x100.png 88w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/projeto-de-desenvolvimento-twitter-531x600.png 531w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/projeto-de-desenvolvimento-twitter-398x450.png 398w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/projeto-de-desenvolvimento-twitter-478x540.png 478w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/projeto-de-desenvolvimento-twitter-150x170.png 150w\" sizes=\"(max-width: 715px) 100vw, 715px\" \/>\r\n<figcaption>Est\u00e1 esperando o que para fazer o seu? \ud83d\ude09<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Qualquer d\u00favida que possa aparecer durante o desenvolvimento, podem comentar ou enviar diretamente para mim: <em>lucas.picollo@geekhunter.com.br<\/em><\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">React tutorial: requisitos<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Os requisitos para conseguir acompanhar o desenvolvimento s\u00e3o:<\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>Conhecimentos em <strong><a href=\"https:\/\/www.geekhunter.com\/pt\/blog\/linguagem-javascript-um-guia-para-iniciantes\/\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"JavaScript (abre numa nova aba)\">JavaScript<\/a><\/strong>;<\/li>\r\n<li>Ter uma vers\u00e3o do servidor baixada na m\u00e1quina local;<\/li>\r\n<li><strong><a href=\"https:\/\/www.geekhunter.com\/pt\/blog\/por-que-usar-node-js-uma-justificativa-passo-a-passo\/\">Node<\/a><\/strong> v12.x.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.geekhunter.com\/pt\/blog\/curso-javascript\/\" target=\"_blank\" rel=\"noreferrer noopener\"><img decoding=\"async\" class=\"wp-image-9731\" src=\"https:\/\/www.geekhunter.com\/pt\/blog\/wp-content\/uploads\/2020\/03\/Curso-JavaScript-1024x336.png\" alt=\"\" \/><\/a><\/figure>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Iniciando o monorepo<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Por motivos de organiza\u00e7\u00e3o e para facilitar o entendimento desse React tutorial, criaremos a parte do cliente no mesmo reposit\u00f3rio que o servidor. Iremos separar cada parte da aplica\u00e7\u00e3o em sua \u00fanica unidade l\u00f3gica (um diret\u00f3rio). Para isso, precisamos separar as partes relacionadas ao servidor e do cliente.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Atualmente nossa aplica\u00e7\u00e3o est\u00e1 da seguinte forma:<\/p>\r\n\r\n\r\n\r\n<div class=\"wp-block-image\">\r\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" width=\"181\" height=\"204\" class=\"wp-image-9735\" src=\"https:\/\/www.geekhunter.com\/pt\/blog\/wp-content\/uploads\/2020\/03\/aplica\u00e7\u00e3o-node.png\" alt=\"aplica\u00e7\u00e3o em react\" srcset=\"https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/aplica\u00e7\u00e3o-node.png 181w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/aplica\u00e7\u00e3o-node-133x150.png 133w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/aplica\u00e7\u00e3o-node-89x100.png 89w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/aplica\u00e7\u00e3o-node-150x169.png 150w\" sizes=\"(max-width: 181px) 100vw, 181px\" \/><\/figure>\r\n<\/div>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Faremos com que a estrutura seja como esta:<\/p>\r\n\r\n\r\n\r\n<div class=\"wp-block-image\">\r\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" width=\"182\" height=\"136\" class=\"wp-image-9736\" src=\"https:\/\/www.geekhunter.com\/pt\/blog\/wp-content\/uploads\/2020\/03\/diret\u00f3rio-aplica\u00e7\u00e3o.png\" alt=\"\" srcset=\"https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/diret\u00f3rio-aplica\u00e7\u00e3o.png 182w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/diret\u00f3rio-aplica\u00e7\u00e3o-150x112.png 150w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/diret\u00f3rio-aplica\u00e7\u00e3o-100x75.png 100w\" sizes=\"(max-width: 182px) 100vw, 182px\" \/><\/figure>\r\n<\/div>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Como primeiro passo, criamos um diret\u00f3rio chamado <em>server<\/em>, onde ficar\u00e1 guardado toda a parte que envolve o servidor.\u00a0<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Ap\u00f3s isso, devemos mover todos os arquivos para esta nova pasta, no entanto, sabemos que nossa aplica\u00e7\u00e3o necessita de muitas depend\u00eancias, e que estas depend\u00eancias s\u00e3o todas alocadas dentro da pasta <em>node_modules<\/em>, o que a torna uma pasta muito pesada de ser movida de um lado para o outro.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Podemos utilizar dos benef\u00edcios do arquivo <em>package.json<\/em> &#8211; que nos permite instalar todas as depend\u00eancias necess\u00e1rias com um \u00fanico comando &#8211; e remover todo o diret\u00f3rio <em>node_modules,<\/em> para depois baix\u00e1-lo j\u00e1 no lugar certo.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Apagamos o diret\u00f3rio e movemos todos os arquivos (menos o diret\u00f3rio <em>.git, <\/em>caso esteja utilizando o git como versionamento<em>)<\/em> para dentro da pasta <em>server, <\/em>de forma que nossa aplica\u00e7\u00e3o ficar\u00e1\u00a0 apenas com a pasta <em>server<\/em> na ra\u00edz.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Podemos reinstalar as depend\u00eancias do servidor que exclu\u00edmos anteriormente, faremos isso acessando o <em>server<\/em> e utilizando o comando <em><code>yarn install (npm install)<\/code>.\u00a0<\/em><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Para iniciarmos o servidor, utilizamos o comando<code> <em>yarn start<\/em><\/code>, que far\u00e1 com que o nosso servidor fique rodando na porta que definimos, no caso a porta padr\u00e3o: 3333.\u00a0<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Caso sua aplica\u00e7\u00e3o n\u00e3o tenha mais o arquivo <em>.env<\/em> podemos copiar o <em>.env.example<\/em> e preencher com as vari\u00e1veis que hav\u00edamos escolhido:<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"669\" height=\"78\" class=\"wp-image-9739\" src=\"https:\/\/www.geekhunter.com\/pt\/blog\/wp-content\/uploads\/2020\/03\/vari\u00e1veis-de-desenvolvimento-de-software-1.png\" alt=\"vari\u00e1veis de desenvolvimento \" srcset=\"https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/vari\u00e1veis-de-desenvolvimento-de-software-1.png 669w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/vari\u00e1veis-de-desenvolvimento-de-software-1-150x17.png 150w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/vari\u00e1veis-de-desenvolvimento-de-software-1-100x12.png 100w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/vari\u00e1veis-de-desenvolvimento-de-software-1-600x70.png 600w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/vari\u00e1veis-de-desenvolvimento-de-software-1-450x52.png 450w\" sizes=\"(max-width: 669px) 100vw, 669px\" \/><\/figure>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Come\u00e7ando nosso React tutorial<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Com as responsabilidades do servidor separadas em um \u00fanico diret\u00f3rio, podemos ent\u00e3o criar o projeto que servir\u00e1 como a parte do<strong><a href=\"https:\/\/www.geekhunter.com\/pt\/blog\/tudo-sobre-html-para-front-ends\/\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" front-end (abre numa nova aba)\"> front-end<\/a><\/strong> da nossa aplica\u00e7\u00e3o.\u00a0<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Utilizaremos<a href=\"https:\/\/reactjs.org\/\" target=\"_blank\" rel=\"noreferrer noopener\"><strong> React JS<\/strong><\/a>, uma biblioteca de c\u00f3digo aberto utilizada para cria\u00e7\u00e3o de interfaces gr\u00e1ficas criada pelo Facebook.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Podemos criar um projeto com esse React tutorial de v\u00e1rias formas, a mais f\u00e1cil delas \u00e9 utilizando uma biblioteca chamada <em><a href=\"https:\/\/github.com\/facebook\/create-react-app\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"create-react-app (abre numa nova aba)\"><strong>create-react-app<\/strong><\/a><\/em>, tamb\u00e9m criada pelo Facebook, que j\u00e1 traz todas as configura\u00e7\u00f5es necess\u00e1rias para rodar uma aplica\u00e7\u00e3o.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Ao longo do tutorial estamos utilizando <em>yarn<\/em> como gerenciador de pacotes, podemos iniciar o<code> create-react-app <\/code>com o comando:<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><em><code>yarn create react-app client<\/code><\/em><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Onde <em>client <\/em>\u00e9 o nome da nossa aplica\u00e7\u00e3o.<\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>Tamb\u00e9m \u00e9 poss\u00edvel utilizar o NPM com o comando <em>npx create-react-app client<\/em><\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Ap\u00f3s o tempo de instala\u00e7\u00e3o e configura\u00e7\u00e3o devemos ter uma estrutura de arquivos como a seguinte:<\/p>\r\n\r\n\r\n\r\n<div class=\"wp-block-image\">\r\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"136\" height=\"199\" class=\"wp-image-9740\" src=\"https:\/\/www.geekhunter.com\/pt\/blog\/wp-content\/uploads\/2020\/03\/estrutura-de-arquivos-1.png\" alt=\"estruturas de arquivos \" srcset=\"https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/estrutura-de-arquivos-1.png 136w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/estrutura-de-arquivos-1-103x150.png 103w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/estrutura-de-arquivos-1-68x100.png 68w\" sizes=\"(max-width: 136px) 100vw, 136px\" \/><\/figure>\r\n<\/div>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Devemos entender a estrutura de pastas para entender como nosso react tutorial ser\u00e1 desenvolvido:<\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li><em>public<\/em>: diret\u00f3rio onde ficam os arquivos que s\u00e3o p\u00fablicos ao browser (<em>index.html, logo.png, favicon.ico)<\/em>;<\/li>\r\n<li><em>src: <\/em>diret\u00f3rio onde ficar\u00e3o nossos arquivos <em>.js ou .jsx<\/em> que s\u00e3o nossos componentes criados nesse React tutorial (veremos mais sobre JSX nos pr\u00f3ximos passos);<\/li>\r\n<li><em>package.json: <\/em>arquivo que cont\u00e9m informa\u00e7\u00f5es, depend\u00eancias e scripts da nossa aplica\u00e7\u00e3o.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Para descobrirmos como a aplica\u00e7\u00e3o funciona podemos ver os scripts que est\u00e3o dispon\u00edveis no arquivo <em>package.json<\/em>:<\/p>\r\n\r\n\r\n\r\n<div class=\"wp-block-image\">\r\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"268\" height=\"103\" class=\"wp-image-9741\" src=\"https:\/\/www.geekhunter.com\/pt\/blog\/wp-content\/uploads\/2020\/03\/package-json.png\" alt=\"scripts no package.json\" srcset=\"https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/package-json.png 268w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/package-json-150x58.png 150w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/package-json-100x38.png 100w\" sizes=\"(max-width: 268px) 100vw, 268px\" \/><\/figure>\r\n<\/div>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li><em>start:<\/em> script para iniciar a aplica\u00e7\u00e3o;<\/li>\r\n<li><em>build: <\/em>script para criar nosso c\u00f3digo pronto para produ\u00e7\u00e3o, contendo apenas arquivos HTML, CSS e Javascript;<\/li>\r\n<li><em>test: <\/em>script para rodar a rotina de testes;<\/li>\r\n<li><em>eject: <\/em>script para extrair os arquivos de configura\u00e7\u00e3o que est\u00e3o abstra\u00eddos pelo create-react-app (geralmente n\u00e3o precisamos utilizar esse script).<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Iniciamos ent\u00e3o a aplica\u00e7\u00e3o atrav\u00e9s do comando <em>yarn start <\/em>(lembre-se de entrar na pasta <em>client<\/em> antes de rodar o script).<\/p>\r\n\r\n\r\n\r\n<div class=\"wp-block-image\">\r\n<figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-9742\" src=\"https:\/\/www.geekhunter.com\/pt\/blog\/wp-content\/uploads\/2020\/03\/aplica\u00e7\u00e3o-react-tutorial.png\" alt=\"app react tutorial \" width=\"316\" height=\"321\" srcset=\"https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/aplica\u00e7\u00e3o-react-tutorial.png 533w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/aplica\u00e7\u00e3o-react-tutorial-148x150.png 148w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/aplica\u00e7\u00e3o-react-tutorial-443x450.png 443w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/aplica\u00e7\u00e3o-react-tutorial-150x152.png 150w\" sizes=\"(max-width: 316px) 100vw, 316px\" \/>\r\n<figcaption>P\u00e1gina inicial da aplica\u00e7\u00e3o<\/figcaption>\r\n<\/figure>\r\n<\/div>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Arquivos que n\u00e3o ser\u00e3o utilizados nesse react tutorial<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Caso voc\u00ea tenha dado uma olhada nos arquivos do projeto deste react tutorial, deve ter percebido que a aplica\u00e7\u00e3o j\u00e1 possui alguns arquivos padr\u00e3o que formam a p\u00e1gina inicial que est\u00e1 sendo mostrada no browser.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Como criaremos nossa pr\u00f3pria interface, podemos remover os arquivos que n\u00e3o utilizaremos e deixar o projeto pronto para que possamos come\u00e7ar, de uma vez por todas, o desenvolvimento do nosso react tutorial.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Os arquivos que podem ser deletados s\u00e3o:<\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li><em>src\/serviceWorkder.js<\/em>;<\/li>\r\n<li><em>src\/logo.svg<\/em>;<\/li>\r\n<li><em>src\/App.test.js<\/em>;<\/li>\r\n<li><em>src\/App.css<\/em>.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Devemos tamb\u00e9m remover as refer\u00eancias feitas a estes arquivos dentro dos outro arquivos.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">index.js:<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/becce3cbc71bc8d7c2ba05c28a6ac753.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">App.js:<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/aba5d048a9fbd2a8285fe815f76a9884.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Se olharmos no browser veremos uma tela branca com o text \u201cApp\u201d escrito no canto superior esquerdo.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Entendendo JSX<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Um dos grandes diferenciais desse React tutorial \u00e9 o fato de lidar com o <strong><a href=\"https:\/\/www.geekhunter.com\/pt\/blog\/tudo-sobre-html-para-front-ends\/\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"HTML (abre numa nova aba)\">HTML<\/a><\/strong> juntamente com o <strong><a href=\"https:\/\/www.geekhunter.com\/pt\/blog\/introducao-ao-javascript-numeros-e-objetos\/\">JavaScript<\/a><\/strong>, trazendo todo o dinamismo do JS para a linguagem de marca\u00e7\u00e3o. Veremos como \u00e9 pr\u00e1tico integrar conceitos de programa\u00e7\u00e3o como itera\u00e7\u00e3o, condicionais e at\u00e9 mesmo opera\u00e7\u00f5es l\u00f3gicas em um \u00fanico react tutorial.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Ao entrarmos no arquivo <em>App.js<\/em>, podemos perceber pontos importantes:<\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>Temos uma fun\u00e7\u00e3o chamada App que n\u00e3o recebe nenhum par\u00e2metro, e que retorna uma <em>tag html <\/em>com uma propriedade parecida com a que conhecemos do <em>html <\/em>padr\u00e3o, <em>className<\/em>. <strong>Isso \u00e9 JSX!\u00a0<\/strong><\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">\u00c9 importante sabermos que as semelhan\u00e7as n\u00e3o s\u00e3o em v\u00e3o, o atributo <em>className <\/em>serve para o mesmo prop\u00f3sito que o atributo <em>class <\/em>em uma tag html padr\u00e3o.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Por\u00e9m, tem o nome diferente devido \u00e0 necessidade do React de ter uma nomenclatura espec\u00edfica para atributos j\u00e1 conhecidos pelo browser e para que n\u00e3o haja conflito entre as propriedades.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Criando nosso primeiro componente<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Para darmos in\u00edcio ao nosso react tutorial, come\u00e7aremos pela parte que toda nossa aplica\u00e7\u00e3o depende, o login.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Podemos implementar uma tela de login b\u00e1sica que pe\u00e7a ao usu\u00e1rio seu login e sua senha e d\u00ea a op\u00e7\u00e3o de se cadastrar, caso o usu\u00e1rio n\u00e3o tenha uma conta.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Nosso componente inicial deve ficar parecido a este <s>bel\u00edssimo<\/s> design:<\/p>\r\n\r\n\r\n\r\n<div class=\"wp-block-image\">\r\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"383\" height=\"270\" class=\"wp-image-9743\" src=\"https:\/\/www.geekhunter.com\/pt\/blog\/wp-content\/uploads\/2020\/03\/p\u00e1gina-inicial.png\" alt=\"p\u00e1gina inicial da aplica\u00e7\u00e3o \" srcset=\"https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/p\u00e1gina-inicial.png 383w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/p\u00e1gina-inicial-150x106.png 150w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/p\u00e1gina-inicial-100x70.png 100w\" sizes=\"(max-width: 383px) 100vw, 383px\" \/><\/figure>\r\n<\/div>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Se quisermos seguir as boas pr\u00e1ticas de uma aplica\u00e7\u00e3o React, devemos separar cada componente em um arquivo espec\u00edfico.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Por padr\u00e3o, os <strong><a href=\"https:\/\/www.geekhunter.com\/pt\/blog\/criando-componentes-react-componentes-de-classe-e-funcional-sem-estado\/\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"componentes React (abre numa nova aba)\">componentes React<\/a><\/strong> que s\u00e3o reutilizados em m\u00faltiplas p\u00e1ginas ficam dentro do diret\u00f3rio <em>src\/components<\/em>, e os que representam p\u00e1ginas ficam no diret\u00f3rio <em>src\/pages<\/em>.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Ambos em diret\u00f3rio com o nome no componente, neste caso <em>src\/pages\/Login, <\/em>em um arquivo index.js.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Criaremos ent\u00e3o, dentro da pasta <em>src\/pages\/Login\/index.js,<\/em> que \u00e9 referente a p\u00e1gina de login, com o seguinte conte\u00fado:<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/e5bee14d511d1029fc213369f70f48e9.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Se abrirmos o browser, vemos que nada aconteceu, certo? A tela continua apenas com a palavra App, isso porque ainda n\u00e3o estamos utilizando nosso componente.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Para que possamos ver como est\u00e1 a parte visual, precisamos importar no arquivo principal o <em>Login <\/em>e utiliz\u00e1-lo como utilizar\u00edamos uma tag HTML.<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/d95f49ea21298bce6e8e36a98c910f18.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Agora \u00e9 poss\u00edvel vermos o feedback visual no browser, no entanto, ainda n\u00e3o est\u00e1 do jeito que gostar\u00edamos. Isso se d\u00e1 pelo fato de ainda n\u00e3o termos criado nenhuma estiliza\u00e7\u00e3o para nossa aplica\u00e7\u00e3o.<\/p>\r\n\r\n\r\n\r\n<div class=\"wp-block-image\">\r\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"397\" height=\"89\" class=\"wp-image-9744\" src=\"https:\/\/www.geekhunter.com\/pt\/blog\/wp-content\/uploads\/2020\/03\/layout-twitter-clone.png\" alt=\"layout twitter clone \" srcset=\"https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/layout-twitter-clone.png 397w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/layout-twitter-clone-150x34.png 150w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/layout-twitter-clone-100x22.png 100w\" sizes=\"(max-width: 397px) 100vw, 397px\" \/><\/figure>\r\n<\/div>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Podemos\u00a0 tamb\u00e9m criar o componente respons\u00e1vel pela cria\u00e7\u00e3o de uma conta que seguir\u00e1 o mesmo padr\u00e3o do componente de login.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Na pasta <em>src\/components\/Register <\/em>criamos um arquivo <em>index.js<\/em> como o seguinte:<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/235a52a517409b016fb1e7f6a55d175d.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Agora temos nossos componentes necess\u00e1rios para que o usu\u00e1rio consiga acessar nossa aplica\u00e7\u00e3o, assim ser\u00e1 poss\u00edvel que o usu\u00e1rio, mesmo sendo novo, consiga entrar na aplica\u00e7\u00e3o para criar seus tweets.\u00a0<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Temos que fazer com que esses componentes sejam utilizados pelo App, por\u00e9m, se adicionarmos o componente diretamente abaixo do Login acabaremos com 2 forms, um embaixo do outro.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">O que realmente queremos que aconte\u00e7a \u00e9 que, dependendo da URL que o usu\u00e1rio acesse, nossa aplica\u00e7\u00e3o mostre o componente correto.\u00a0<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Implementando rotas<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">A implementa\u00e7\u00e3o de rotas \u00e9 uma das partes fundamentais de uma aplica\u00e7\u00e3o React, com ela podemos criar diferentes p\u00e1ginas, links din\u00e2micos e sub-rotas da mesma forma que criamos componentes visuais.\u00a0<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Para implementarmos as rotas da nossa aplica\u00e7\u00e3o, utilizaremos uma biblioteca chamada <strong><em><a href=\"https:\/\/reacttraining.com\/react-router\/web\/\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"react-router (abre numa nova aba)\">react-router<\/a><\/em><\/strong>, que \u00e9 a biblioteca mais utilizada para cria\u00e7\u00e3o de rotas em aplica\u00e7\u00f5es React.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Instalamos no projeto atrav\u00e9s do comando:<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><em><code>yarn add react-router-dom<\/code><\/em><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Por padr\u00e3o criamos nossas rotas no arquivo <em>src\/Routes\/index.js<\/em>, da seguinte forma:<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/f4b8d3a0879ca27d5af5b96701b8bdf4.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>Importamos do <em>react-router-dom:<\/em>\r\n<ul>\r\n<li><em>BrowserRouter: <\/em>componente respons\u00e1vel pelo controle dos estados da URL da aplica\u00e7\u00e3o;<\/li>\r\n<li><em>Switch: <\/em>sistema de match da rota e URL;<\/li>\r\n<li><em>Route: <\/em>declara uma rota e qual componente deve ser renderizado quando a rota for ativada.<\/li>\r\n<\/ul>\r\n<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Na declara\u00e7\u00e3o da rota, informamos a URL que deveria ativa-l\u00e1 e o componente que queremos que seja renderizado. Neste caso, o componente login na URL \/ que \u00e9 referente a ra\u00edz da aplica\u00e7\u00e3o.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">* A propriedade exact informa ao Switch que a rota a ser ativada deve ser exatamente igual a que foi atribu\u00edda, se n\u00e3o adicion\u00e1ssemos isso a rota <em>\/register<\/em> tamb\u00e9m ativaria a rota \/.\u00a0<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Devemos ent\u00e3o importar este componente no arquivo <em>App.js<\/em> da seguinte forma:<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/5919a6460c637e031d89ca228afc243e.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Estilizando componentes<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Voc\u00ea deve estar percebendo que, at\u00e9 agora, nossos componentes s\u00e3o apenas <em>tags html <\/em>sem estiliza\u00e7\u00e3o nenhuma, apenas as caracter\u00edsticas padr\u00e3o implementadas pelo browser.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Podemos &#8211; e devemos &#8211; criar estilos pr\u00f3prios a nossos componentes para que expressem mais nossa identidade.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Para criarmos estilos, podemos usar a abordarem do CSS3, selecionando componentes pela classe, pelo id ou pela pr\u00f3pria tag html e atribuindo CSS ao componente escolhido.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">No entanto, como estamos criando uma aplica\u00e7\u00e3o com esse React tutorial, nada melhor que utilizarmos uma biblioteca que junta o CSS com JS para facilitar o desenvolvimento!<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Existem diversas solu\u00e7\u00f5es que trazem o conceito de <em>CSS-in-JS<\/em> e uma biblioteca muito conhecida \u00e9 a chamada:<strong><a href=\"https:\/\/styled-components.com\/\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" styled-components (abre numa nova aba)\"> styled-components<\/a><\/strong>, com ela criamos componentes desse React tutorial que s\u00e3o respons\u00e1veis pela estiliza\u00e7\u00e3o.\u00a0<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Baixaremos o styled-components atrav\u00e9s do comando:<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><em><code>yarn add styled-components<\/code><\/em><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Como nosso primeiro componentes estilizado, criaremos o estilo da p\u00e1gina de login. Para isso come\u00e7amos criando um componente que servir\u00e1 de estrutura para todas as p\u00e1ginas, chamaremos de Layout.\u00a0<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Devemos criar um novo componente na pasta <em>src\/components\/Layout\/index.js<\/em> que ficaria como o seguinte:<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/886c9e3ac2d4fd015c172131fad5d5f0.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Criamos uma fun\u00e7\u00e3o que representa nosso componente Layout.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Essa fun\u00e7\u00e3o recebe como argumento uma propriedade chamada <em>props <\/em>que \u00e9 um objeto com diferentes propriedades do nosso componente (ainda n\u00e3o passamos pela explica\u00e7\u00e3o desse conceito do React, aprenderemos em uma pr\u00f3xima se\u00e7\u00e3o).<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Agora, devemos criar a estiliza\u00e7\u00e3o deste componente, na pasta do componente criamos um arquivo chamado <code>src\/components\/Layout\/<em>styles.js<\/em><\/code> e nele colocaremos todas as fun\u00e7\u00f5es respons\u00e1veis pela estiliza\u00e7\u00e3o do componente.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">O arquivo fica da seguinte forma:<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/a30abb20e7cb8d495818d2b56e9be091.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Nosso componente <em>Layout.js <\/em>tem que ser alterado para utilizar os estilos que criamos, para isso importamos os componentes que criamos com o <em>styled-components <\/em>e substitu\u00edmos as tags html que est\u00e1vamos usando:<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/70658da6b03b35b5de42b50725480116.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Agora temos que fazer nosso componente ser utilizado, no componente <em>src\/pages\/Login <\/em>inserimos o layout:<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/4f590220d53750c2607568f36f4e2dc2.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Podemos notar uma apar\u00eancia melhor no browser, por\u00e9m ainda devemos criar a estiliza\u00e7\u00e3o para componente de login:<\/p>\r\n\r\n\r\n\r\n<div class=\"wp-block-image\">\r\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"475\" height=\"137\" class=\"wp-image-9745\" src=\"https:\/\/www.geekhunter.com\/pt\/blog\/wp-content\/uploads\/2020\/03\/estiliza\u00e7\u00e3o-componente-de-login.png\" alt=\"estiliza\u00e7\u00e3o componente de login \" srcset=\"https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/estiliza\u00e7\u00e3o-componente-de-login.png 475w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/estiliza\u00e7\u00e3o-componente-de-login-150x43.png 150w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/estiliza\u00e7\u00e3o-componente-de-login-100x29.png 100w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/estiliza\u00e7\u00e3o-componente-de-login-450x130.png 450w\" sizes=\"(max-width: 475px) 100vw, 475px\" \/><\/figure>\r\n<\/div>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Seguiremos o mesmo padr\u00e3o de cria\u00e7\u00e3o de componentes de estilo para o pr\u00f3prio Login, criamos um arquivo <em>src\/pages\/Login\/styles.js<\/em>.<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/3d7d668eb8959de5c76da183491e7fd1.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">E utilizaremos da seguinte forma:<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/0f34dfe668c427a3d4a79abcc0cd864d.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Se acessarmos pelo browser veremos o seguinte feedback visual:<\/p>\r\n\r\n\r\n\r\n<div class=\"wp-block-image\">\r\n<figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-9746\" src=\"https:\/\/www.geekhunter.com\/pt\/blog\/wp-content\/uploads\/2020\/03\/programa\u00e7\u00e3o-twitter.png\" alt=\"feedback programa\u00e7\u00e3o\" width=\"444\" height=\"307\" srcset=\"https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/programa\u00e7\u00e3o-twitter.png 543w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/programa\u00e7\u00e3o-twitter-150x104.png 150w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/programa\u00e7\u00e3o-twitter-100x69.png 100w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/programa\u00e7\u00e3o-twitter-450x311.png 450w\" sizes=\"(max-width: 444px) 100vw, 444px\" \/><\/figure>\r\n<\/div>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Note que o link para criar conta nos redireciona para a p\u00e1gina de registro.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Devemos criar o componente de estiliza\u00e7\u00e3o para a p\u00e1gina <em>Register <\/em>seguindo o mesmo padr\u00e3o que a p\u00e1gina de de login. Utilizaremos o componente <em>Layout <\/em>dentro da p\u00e1gina <em>Register <\/em>e a mesma estiliza\u00e7\u00e3o do componente login.<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/117d05ea122938c2479216fe703ba19d.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Lidando com estados<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">At\u00e9 agora, nossa aplica\u00e7\u00e3o ainda n\u00e3o possui nenhuma intera\u00e7\u00e3o com usu\u00e1rio, fora a capacidade de escrever no elemento <em>&lt;input&gt;<\/em> que \u00e9 uma intera\u00e7\u00e3o que o pr\u00f3prio browser implementa.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">No entanto, se quisermos que usufruir ao m\u00e1ximo as capacidades desse React tutorial, devemos utilizar as funcionalidades que a biblioteca nos oferece.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Uma das funcionalidades mais populares do React \u00e9 o chamado <em>state<\/em>, que representa o estado de nossa aplica\u00e7\u00e3o, seja um texto em um <em>input<\/em>, o estado de um checkbox ou a disponibilidade de um bot\u00e3o.\u00a0<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Para termos acesso ao estado de um <em>input <\/em>por exemplo, utilizaremos um dos conceitos mais relevantes do ecossistema React, os chamados <strong><em><a href=\"https:\/\/reactjs.org\/docs\/hooks-intro.html\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"hooks (abre numa nova aba)\">hooks<\/a><\/em><\/strong>.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Hooks s\u00e3o fun\u00e7\u00f5es com prop\u00f3sitos espec\u00edficos dentro de uma aplica\u00e7\u00e3o que utiliza React, como guardar estados (<em>useState<\/em>), realizar algum efeito (chamada de API, manuseio de dados &#8211; <em>useEffect<\/em>) e para diversas outras funcionalidades.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Todos os hooks seguem o padr\u00e3o de ter o prefixo <em>use<\/em>!<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">No caso de queremos guardar o texto escrito pelo usu\u00e1rio, devemos utilizar o hook que cuida de estados, tendo em vista que o texto representa como nosso componente se encontra em um determinado momento.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Para isso, importamos do React atrav\u00e9s de um destruct o hook <em>useState<\/em>.\u00a0<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Esse hook funciona como uma fun\u00e7\u00e3o, por\u00e9m com duas caracter\u00edsticas peculiares:<\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>Deve ser chamado no in\u00edcio do componente;<\/li>\r\n<li>N\u00e3o pode ser chamado dentro de uma condi\u00e7\u00e3o ou itera\u00e7\u00e3o.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Vejamos na pr\u00e1tica como isso funciona, implementamos a intera\u00e7\u00e3o do usu\u00e1rio com a <em>textarea <\/em>da seguinte forma:<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/3182549c46b1383d3f449b4a84458b98.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>Importamos <em>useState<\/em> do React;<\/li>\r\n<li>Chamamos o <em>useState <\/em>dentro do componente passando como argumento o estado inicial que quisermos;<\/li>\r\n<li>Essa fun\u00e7\u00e3o retorna um array contendo o estado atual e uma fun\u00e7\u00e3o que altera este estado;<\/li>\r\n<li>Atribu\u00edmos o valor do input a essa vari\u00e1vel <em>username<\/em>;<\/li>\r\n<li>Imprimimos no console o estado da vari\u00e1vel <em>username<\/em> cada vez que ela \u00e9 alterada.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Temos agora o estado relativo ao atributo <em>username<\/em> que representa o texto que o usu\u00e1rio escreveu no input<em>.<\/em> Agora, ao escrevermos algum texto na <em>input <\/em>de nome de usu\u00e1rio ser\u00e1 poss\u00edvel ver no console o novo estado a cada altera\u00e7\u00e3o:<\/p>\r\n\r\n\r\n\r\n<div class=\"wp-block-image\">\r\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"190\" height=\"237\" class=\"wp-image-9747\" src=\"https:\/\/www.geekhunter.com\/pt\/blog\/wp-content\/uploads\/2020\/03\/atributo-username.png\" alt=\"atributo username \" srcset=\"https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/atributo-username.png 190w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/atributo-username-120x150.png 120w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/atributo-username-80x100.png 80w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/atributo-username-150x187.png 150w\" sizes=\"(max-width: 190px) 100vw, 190px\" \/><\/figure>\r\n<\/div>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">* Podemos excluir o <em>console.log <\/em>do nosso componente agora, para n\u00e3o ficarmos expondo nosso estado ao usu\u00e1rio.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Com essa implementa\u00e7\u00e3o, podemos ter acesso ao conte\u00fado que o usu\u00e1rio escreve no componente de input. Devemos fazer a mesma implementa\u00e7\u00e3o para o input de senha, para que seja poss\u00edvel que fa\u00e7amos a intera\u00e7\u00e3o de login e de registro.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Lembre-se que os hooks podem ser utilizados in\u00fameras vezes dentro de um componente, precisamos apenas declarar um novo <em>useState<\/em> para o conte\u00fado da senha.<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/f714eff41d7e2fb7406d864739b970fb.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Se formos preenchendo os campos, podemos ver a feedback no console dos dados que escrevemos. Devemos agora remover o <em>console.log <\/em>para que n\u00e3o seja poss\u00edvel ver os dados do usu\u00e1rio enquanto \u00e9 digitado.\u00a0<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Replique este comportamento no componente <em>Register<\/em>.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Cria\u00e7\u00e3o de um novo usu\u00e1rio<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Agora que temos nossas rotas definidas, os estilos j\u00e1 implementados e j\u00e1 lidamos com os estados da aplica\u00e7\u00e3o, podemos come\u00e7ar a fazer as intera\u00e7\u00f5es da parte do cliente &#8211; com esse React tutorial &#8211;\u00a0 com a parte do <strong><a href=\"https:\/\/www.geekhunter.com\/pt\/blog\/como-comecar-em-web-back-end-do-zero\/\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"back-end (abre numa nova aba)\">back-end<\/a> &#8211; <a href=\"https:\/\/www.geekhunter.com\/pt\/blog\/node-js-tutorial-twitter-clone-full-stack-app-parte-1\/\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"NodeJS (abre numa nova aba)\">NodeJS<\/a><\/strong>.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Para que essa comunica\u00e7\u00e3o possa ser feita com sucesso, devemos fazer com que o servidor esteja rodando juntamente com a aplica\u00e7\u00e3o do front.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Abra um novo terminal, entre na pasta <em>server <\/em>\u00a0na ra\u00edz do projeto e execute o comando yarn start. Se tudo ocorreu corretamente, devemos receber a seguinte mensagem no console:<\/p>\r\n\r\n\r\n\r\n<div class=\"wp-block-image\">\r\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"278\" height=\"100\" class=\"wp-image-9748\" src=\"https:\/\/www.geekhunter.com\/pt\/blog\/wp-content\/uploads\/2020\/03\/yarn-start.png\" alt=\" yarn start \" srcset=\"https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/yarn-start.png 278w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/yarn-start-150x54.png 150w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/yarn-start-100x36.png 100w\" sizes=\"(max-width: 278px) 100vw, 278px\" \/><\/figure>\r\n<\/div>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Caso n\u00e3o tenha conseguido ver esta mensagem, algo deve ter sa\u00eddo do planejado. Os poss\u00edveis problemas podem ser: a aus\u00eancia do arquivo de vari\u00e1veis de ambiente do projeto <em>(.env)<\/em> ou a falta de instala\u00e7\u00e3o das depend\u00eancias &#8211; que pode ser resolvido rodando o comando <em>yarn install <\/em>ou <em>npm install<\/em>.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">As intera\u00e7\u00f5es com o back-end s\u00e3o feitas via HTTP, para isso utilizaremos uma library chamada <strong><em><a href=\"https:\/\/github.com\/axios\/axios\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"axios (abre numa nova aba)\">axios<\/a><\/em><\/strong>. Com ela, podemos realizar todos os m\u00e9todos HTTP (GET, POST, UPDATE, DELETE) para uma URL espec\u00edfica.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Devemos baixar o axios no projeto com o comando:<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><code> <em>yarn add axios<\/em><\/code><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">No bot\u00e3o de <em>entrar<\/em>, devemos criar uma fun\u00e7\u00e3o que ser\u00e1 chamada toda vez que o usu\u00e1rio clicar no bot\u00e3o. Para isso utilizaremos a propriedade <em>onClick<\/em> do bot\u00e3o que recebe uma fun\u00e7\u00e3o de callback.<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/1485e9b0899d5800d0a286e33b0b07c3.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Perceba que todas vez que clicamos no bot\u00e3o a p\u00e1gina \u00e9 recarregada e n\u00e3o vemos nada no console.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Isso acontece por um comportamento padr\u00e3o do browser, como queremos controlar isso, utilizamos o m\u00e9todo <em>preventDefault<\/em> do argumento <em>event <\/em>para que o browser n\u00e3o fa\u00e7a nenhuma a\u00e7\u00e3o padr\u00e3o.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Agora, se preenchermos os campos e apertarmos entrar, veremos o conte\u00fado sendo impresso no console sem a p\u00e1gina recarregar. Por\u00e9m, n\u00e3o queremos que o usu\u00e1rio possa entrar sem digitar nenhum nome de usu\u00e1rio ou senha, tratamos isso adicionando a propriedade <em>required <\/em>a cada input do componente.\u00a0<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Se ativarmos a fun\u00e7\u00e3o de <em>entrar <\/em>agora, sem nenhum campo preenchido, veremos um feedback do pr\u00f3prio browser falando que o campo \u00e9 obrigat\u00f3rio.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Para implementarmos a intera\u00e7\u00e3o do client com o servidor, devemos chamar o <em>axios <\/em>na fun\u00e7\u00e3o de callback do bot\u00e3o de entrar, utilizando o m\u00e9todo POST na rota de login do servidor, <em>SERVER_URL<\/em>\/login.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">O c\u00f3digo fica assim:<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/0c9e16f7730c5532a93078d7c4fe0e41.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>Importamos o axios;<\/li>\r\n<li>Fazemos nossa fun\u00e7\u00e3o de tratamento de login como uma fun\u00e7\u00e3o ass\u00edncrona;<\/li>\r\n<li>Envolvemos a chamada em um try\/catch para tratar poss\u00edveis erros;<\/li>\r\n<li>Chamamos o m\u00e9todo POST do axios que serve para mandar uma request POST para o servidor passando como argumento:\r\n<ul>\r\n<li>A URL do servidor com o rota de login;<\/li>\r\n<li>Um objeto contendo o nome do usu\u00e1rio e a senha.<\/li>\r\n<\/ul>\r\n<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Se olharmos no console, veremos um erro como este:<\/p>\r\n\r\n\r\n\r\n<div class=\"wp-block-image\">\r\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"396\" height=\"94\" class=\"wp-image-9749\" src=\"https:\/\/www.geekhunter.com\/pt\/blog\/wp-content\/uploads\/2020\/03\/erro-localhost.png\" alt=\"erro localhost\" srcset=\"https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/erro-localhost.png 396w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/erro-localhost-150x36.png 150w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/erro-localhost-100x24.png 100w\" sizes=\"(max-width: 396px) 100vw, 396px\" \/><\/figure>\r\n<\/div>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Isso acontece pois o nome de usu\u00e1rio que criamos n\u00e3o foi encontrado pelo servidor. Para conseguirmos acessar a aplica\u00e7\u00e3o precisamos ter um usu\u00e1rio criado, devemos ent\u00e3o implementar a parte de registro de usu\u00e1rio e depois voltaremos para a parte de login.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Na p\u00e1gina de cadastro criaremos a mesma estrutura para comunicar um novo usu\u00e1rio sendo criado no servidor. Nosso componente ficaria como este:<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/6396c73fca392433c1e14345ef0ff44e.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>Importamos <em>useState <\/em>do React;<\/li>\r\n<li>Importamos <em>useHistory <\/em>que \u00e9 um custom hook do react-router para lidar com hist\u00f3rico do browser;<\/li>\r\n<li>Declaramos uma vari\u00e1vel <em>history <\/em>usando o <em>useHistory<\/em>;<\/li>\r\n<li>Criamos a fun\u00e7\u00e3o que trata o registro de um novo usu\u00e1rio;<\/li>\r\n<li>Caso tudo ocorra bem redirecionamos o usu\u00e1rio para tela de login usando o m\u00e9todo <em>push<\/em> do objeto <em>history<\/em>.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Caso tudo ocorra bem, podemos criar um usu\u00e1rio novo preenchendo o nome do usu\u00e1rio e senha,\u00a0 e recebendo como feedback do servidor um objeto como este:<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"742\" height=\"153\" class=\"wp-image-9750\" src=\"https:\/\/www.geekhunter.com\/pt\/blog\/wp-content\/uploads\/2020\/03\/feedback-do-servidor.png\" alt=\" feedback do servidor \" srcset=\"https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/feedback-do-servidor.png 742w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/feedback-do-servidor-150x31.png 150w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/feedback-do-servidor-100x21.png 100w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/feedback-do-servidor-600x124.png 600w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/feedback-do-servidor-450x93.png 450w\" sizes=\"(max-width: 742px) 100vw, 742px\" \/><\/figure>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">No entanto, caso o username j\u00e1 exista, devemos retornar um feedback ao usu\u00e1rio informando o erro. Faremos isso utilizando um outro <em>useState<\/em> espec\u00edfico para o erro.<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/45a3470f6bb6621f0c0f4383e5c7c946.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/7136f1cf4ed5d4b8ce887feb5869e060.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<div class=\"wp-block-image\">\r\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"494\" height=\"335\" class=\"wp-image-9751\" src=\"https:\/\/www.geekhunter.com\/pt\/blog\/wp-content\/uploads\/2020\/03\/aplica\u00e7\u00e3o-twitter.png\" alt=\"aplica\u00e7\u00e3o twitter\" srcset=\"https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/aplica\u00e7\u00e3o-twitter.png 494w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/aplica\u00e7\u00e3o-twitter-150x102.png 150w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/aplica\u00e7\u00e3o-twitter-100x68.png 100w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/aplica\u00e7\u00e3o-twitter-450x305.png 450w\" sizes=\"(max-width: 494px) 100vw, 494px\" \/><\/figure>\r\n<\/div>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Agora podemos voltar ao componente de login, se tentarmos logar com a conta que criamos anteriormente devemos receber este feedback no console.<\/p>\r\n\r\n\r\n\r\n<div class=\"wp-block-image\">\r\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"718\" height=\"130\" class=\"wp-image-9752\" src=\"https:\/\/www.geekhunter.com\/pt\/blog\/wp-content\/uploads\/2020\/03\/feedback-do-servidor-2.png\" alt=\"feedback do servidor\" srcset=\"https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/feedback-do-servidor-2.png 718w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/feedback-do-servidor-2-150x27.png 150w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/feedback-do-servidor-2-100x18.png 100w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/feedback-do-servidor-2-600x109.png 600w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/feedback-do-servidor-2-450x81.png 450w\" sizes=\"(max-width: 718px) 100vw, 718px\" \/><\/figure>\r\n<\/div>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Perceba que recebemos do servidor um token de autentica\u00e7\u00e3o que usaremos para saber se o usu\u00e1rio est\u00e1 logado ou n\u00e3o. Para isso, devemos guardar este token em algum lugar para que possamos utiliz\u00e1-lo nas pr\u00f3ximas requisi\u00e7\u00f5es que fizermos.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">A forma mais f\u00e1cil de fazer isso \u00e9 guardar o token no localStorage, um espa\u00e7o no browser feito especificamente para guardar informa\u00e7\u00f5es n\u00e3o t\u00e3o grandes que devem ser mantidas mesmo se p\u00e1gina for atualizada.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Para implementarmos essa fun\u00e7\u00e3o, devemos alterar nosso m\u00e9todo de tratamento de login para que fique da seguinte forma:<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/af80c86e1f7ce99a5e4b64751cd4d23c.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Para termos acesso \u00e0s informa\u00e7\u00f5es do usu\u00e1rio em nossa aplica\u00e7\u00e3o, devemos conseguir extrair do JWT quem \u00e9 o usu\u00e1rio logado.O decode do token \u00e9 feito atrav\u00e9s da mesma lib que usamos para cria-lo, <em>jsonwebtoken<\/em>.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><code><em>yarn add jsonwebtoken<\/em><\/code><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Os dados do usu\u00e1rios s\u00e3o acessados fazendo o <em>decode<\/em> do token que o autentica, no caso no c\u00f3digo ficaria como o seguinte:<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/e43f1fefdba69b1228f6bc2b237c24dd.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Antes de avan\u00e7armos para pr\u00f3xima etapa do desenvolvimento desse react tutorial, devemos fazer com que a URL do servidor seja uma vari\u00e1vel de ambiente para que possamos alter\u00e1-la para um URL real caso formos dar deploy na aplica\u00e7\u00e3o.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Felizmente o <em>create-react-app<\/em> faz com que o uso de vari\u00e1veis de ambiente nesse React tutorial sejam muito simples de serem usadas!<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Basta que criemos um arquivo <em>.env<\/em> na ra\u00edz do projeto e criemos as vari\u00e1veis iniciando por REACT_APP_. Nesse caso nossa variav\u00e9l ser\u00e1 REACT_APP_SERVER_URL=http:\/\/localhost:3333.<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/2ef7d332655e577a6ac95a8d9981ac39.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Com isso, terminamos a parte de autentica\u00e7\u00e3o do usu\u00e1rio, podemos ent\u00e3o come\u00e7ar a implementar a parte de cria\u00e7\u00e3o de tweets.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Componente de cria\u00e7\u00e3o de tweets<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">O primeiro passo para criar a p\u00e1gina, que ser\u00e1 a Home do usu\u00e1rio, \u00e9 criar na pasta <em>src\/pages, <\/em>uma pasta espec\u00edfica para o componente e adicionar essa nova rota ao arquivo de rotas.<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/02f33c8e415947c45adb784f8268a271.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/17b0b43e6f4fe771fcadc1d61326160b.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Ao entrarmos na aplica\u00e7\u00e3o, somos redirecionados para esta p\u00e1gina. Como estamos fazendo deste react tutorial um clone do Twitter, precisaremos dos componentes principais que formam a interface do Twitter.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Um destes componentes \u00e9 a caixa de texto onde s\u00e3o escritos os tweets.\u00a0<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Ap\u00f3s juntar todas minhas habilidades de <strong><a href=\"https:\/\/www.geekhunter.com\/pt\/blog\/desenvolvedor-ux-como-aprimorar-suas-skills\/\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"UX\/UI (abre numa nova aba)\">UX\/UI<\/a><\/strong>, cheguei a esta interface que criaremos como nosso componente de cria\u00e7\u00e3o de tweets.<\/p>\r\n\r\n\r\n\r\n<div class=\"wp-block-image\">\r\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"581\" height=\"172\" class=\"wp-image-9753\" src=\"https:\/\/www.geekhunter.com\/pt\/blog\/wp-content\/uploads\/2020\/03\/interface-clone-twitter.png\" alt=\"habilidades de UX\/UI\" srcset=\"https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/interface-clone-twitter.png 581w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/interface-clone-twitter-150x44.png 150w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/interface-clone-twitter-100x30.png 100w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/interface-clone-twitter-450x133.png 450w\" sizes=\"(max-width: 581px) 100vw, 581px\" \/><\/figure>\r\n<\/div>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Chamaremos esse componente de <em>TweetForm,\u00a0 <\/em>devemos cri\u00e1-lo na pasta <em>src\/components\/TweetForm\/index.js<\/em>:<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/505a6b94365a3953b5e77de717693da6.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">A estiliza\u00e7\u00e3o ficaria como a seguinte: (<em>src\/components\/TweetForm\/styles.js)<\/em><\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/a4882b995ba289114f91fdcd2587a698.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Em nosso componente <em>TweetForm <\/em>importamos este componente Container, e subsititu\u00edmos a tag html <em>&lt;div&gt;<\/em> pelo Container da seguinte forma:<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/483a6f0f22024a0ee3de0e60f8673c19.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Devemos ent\u00e3o importar na p\u00e1gina Home este novo componente.<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/b5f134f82f03831738c1af5ac5158e9a.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Se acessarmos <em>localhost:3000\/home<\/em> devemos ver esta interface.<\/p>\r\n\r\n\r\n\r\n<div class=\"wp-block-image\">\r\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"157\" class=\"wp-image-9754\" src=\"https:\/\/www.geekhunter.com\/pt\/blog\/wp-content\/uploads\/2020\/03\/interface-melhorada-twitter.png\" alt=\"interface melhorada twitter\" srcset=\"https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/interface-melhorada-twitter.png 624w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/interface-melhorada-twitter-150x38.png 150w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/interface-melhorada-twitter-100x25.png 100w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/interface-melhorada-twitter-600x151.png 600w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/interface-melhorada-twitter-450x113.png 450w\" sizes=\"(max-width: 624px) 100vw, 624px\" \/><\/figure>\r\n<\/div>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Devemos implementar o estado desse componente, juntamente com a fun\u00e7\u00e3o que criar\u00e1 o tweet no servidor. Faremos da seguinte forma:<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/03fd8718f8dd6945ab2f078a9349b141.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>Importamos <em>useState <\/em>do React;<\/li>\r\n<li>Criamos um estado referente ao texto escrito na <em>textarea<\/em>;<\/li>\r\n<li>Criamos uma fun\u00e7\u00e3o que ser\u00e1 chamada quando o bot\u00e3o de enviar for ativado;\r\n<ul>\r\n<li>Nessa fun\u00e7\u00e3o come\u00e7amos buscando o token que estava guardado no LocalStorage;<\/li>\r\n<li>Criamos uma requisi\u00e7\u00e3o do tipo POST no endpoint de cria\u00e7\u00f5a de tweet, passando o conte\u00fado do tweet e o token de autoriza\u00e7\u00e3o;<\/li>\r\n<\/ul>\r\n<\/li>\r\n<li>Limpamos o conte\u00fado da <em>textarea<\/em>.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Se tudo ocorreu como esperado, devemos ter um feedback como este no console:<\/p>\r\n\r\n\r\n\r\n<div class=\"wp-block-image\">\r\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"569\" height=\"110\" class=\"wp-image-9755\" src=\"https:\/\/www.geekhunter.com\/pt\/blog\/wp-content\/uploads\/2020\/03\/feedback-do-console.png\" alt=\"feedback do console \" srcset=\"https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/feedback-do-console.png 569w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/feedback-do-console-150x29.png 150w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/feedback-do-console-100x19.png 100w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/feedback-do-console-450x87.png 450w\" sizes=\"(max-width: 569px) 100vw, 569px\" \/><\/figure>\r\n<\/div>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Rotas privadas<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Tudo parece estar funcionando corretamente, por\u00e9m nossa aplica\u00e7\u00e3o tem um problema que ainda n\u00e3o tratamos . Abra uma janela an\u00f4nima e acesse a url <em>localhost:3000\/home<\/em>, o que acontece? Conseguiu descobrir?<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">O problema que estamos tendo \u00e9 a falta de autentica\u00e7\u00e3o para as rotas, um usu\u00e1rio que acesse diretamente a p\u00e1gina de home ter\u00e1 acesso \u00e0s funcionalidades de criar um tweet mesmo sem estar logado.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">N\u00e3o devemos permitir que isso aconte\u00e7a, para isso devemos criar rotas que exijam que o usu\u00e1rio esteja logado para que possa acessar.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Na pasta <em>Routes <\/em>devemos criar um componente chamada AuthRoute, o qual servir\u00e1 como barreira para rotas que necessitam de autentica\u00e7\u00e3o. O componente ficaria como o seguinte:<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/568799f1890e0e89ec33a384d79966e9.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>Importamos a Route e <em>useHistory<\/em> do <code>react-router-dom<\/code>;<\/li>\r\n<li>Criamos um componente que checa se h\u00e1 o SESSION_TOKEN no localStorage;\r\n<ul>\r\n<li>Caso n\u00e3o haja, o usu\u00e1rio \u00e9 redirecionado para a p\u00e1gina de login;<\/li>\r\n<li>Caso haja o componente \u00e9 renderizado normalmente.<\/li>\r\n<\/ul>\r\n<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">\u00a0Agora, todas as rotas, que devem ser restritas ao usu\u00e1rio que n\u00e3o est\u00e1 logado, devem utilizar o componente AuthRoute ao inv\u00e9s do Route do <em>react-router-dom.<\/em><\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Listagem de tweets<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Os \u00faltimos componentes que est\u00e3o faltando para nossa aplica\u00e7\u00e3o ficar completa s\u00e3o: o <em>card <\/em>de um tweet e a listagem de tweets.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Para implementarmos a listagem devemos criar o arquivo <em>src\/components\/TweetList\/index.js<\/em>e implement\u00e1-lo como o seguinte:<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/599967dba858efb80f4ba36422fcdfb2.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>Criamos um componente <em>TweetList <\/em>seguindo o padr\u00e3o dos demais componentes;<\/li>\r\n<li>Esse componente, recebe como um par\u00e2metro um argumento chamado <em>props<\/em>;<\/li>\r\n<li>Imprimimos o objeto <em>props<\/em>.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Entendendo props<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">O conceito de props \u00e9 muito importante nesse react tutorial, inclusive, \u00e9 um conceito importante para o React no geral, com ele \u00e9 poss\u00edvel reutilizarmos componentes com dados diferentes. Na pr\u00e1tica, os <em>props<\/em> s\u00e3o os atributos que o nosso elemento recebe, no caso do <em>TweetList<\/em> uma lista de tweets que ser\u00e1 renderizada.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Para que o nosso componente tenha acesso a prop <em>tweets<\/em>, devemos fazer com que o componente passe esta propriedade a ele. Na p\u00e1gina Home, ao renderizar o <em>TweetList<\/em>, adicionamos ao componente um atributo chamado tweets e vemos como o componente se comporta.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Home:<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/24430cdf495e6f17a32559852bdfb366.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">No console devemos ter o seguinte feedback:<\/p>\r\n\r\n\r\n\r\n<div class=\"wp-block-image\">\r\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"240\" height=\"150\" class=\"wp-image-9756\" src=\"https:\/\/www.geekhunter.com\/pt\/blog\/wp-content\/uploads\/2020\/03\/array-feedback.png\" alt=\"array \" srcset=\"https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/array-feedback.png 240w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/array-feedback-150x94.png 150w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/array-feedback-100x63.png 100w\" sizes=\"(max-width: 240px) 100vw, 240px\" \/><\/figure>\r\n<\/div>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">O atributo <em>tweets<\/em> que passamos ao nosso componente est\u00e1 sendo impresso no console, isso significa que agora temos acesso aos tweets dentro do componente <em>TweetList.<\/em><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Para renderizarmos uma lista, devemos percorrer o <strong><a href=\"https:\/\/www.geekhunter.com\/pt\/blog\/arrays-em-javascript\/\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"array  (abre numa nova aba)\">array <\/a><\/strong>retornando o elemento de nossa escolha. A renderiza\u00e7\u00e3o ficaria como a seguinte:<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/004a1ea4d4a5c5cb9c6107520c6acecf.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>Criamos uma lista n\u00e3o ordenada (ul);<\/li>\r\n<li>Percorremos o array de tweets utilizando um map, pegando o elemento e o index para renderizar um item da lista.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">* A propriedade <em>key<\/em> \u00e9 obrigat\u00f3ria nesse react tutorial e deve ser \u00fanica para cada elemento, para que o React saiba em qual elemento est\u00e1 sendo feita a intera\u00e7\u00e3o.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">No browser, devemos ter uma interface assim:<\/p>\r\n\r\n\r\n\r\n<div class=\"wp-block-image\">\r\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"656\" height=\"143\" class=\"wp-image-9757\" src=\"https:\/\/www.geekhunter.com\/pt\/blog\/wp-content\/uploads\/2020\/03\/interface-no-browser.png\" alt=\"interface do browser \" srcset=\"https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/interface-no-browser.png 656w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/interface-no-browser-150x33.png 150w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/interface-no-browser-100x22.png 100w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/interface-no-browser-600x131.png 600w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/interface-no-browser-450x98.png 450w\" sizes=\"(max-width: 656px) 100vw, 656px\" \/><\/figure>\r\n<\/div>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Para que possamos pegar os tweets a partir do nosso servidor, precisaremos implementar um novo hook do React, o <em>useEffect<\/em>.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Com ele podemos fazer intera\u00e7\u00f5es com diferentes fontes e em diferentes est\u00e1gios do nosso componente.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">A sintaxe do <em>useEffect<\/em> \u00e9 um pouco diferente do <em>useState<\/em>, ele recebe uma fun\u00e7\u00e3o como argumento que ser\u00e1 rodada em determinado momento. A utiliza\u00e7\u00e3o seria como a seguinte:<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/149b6a28bea3c5e2f288e4fcfc812168.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>Importamos <em>useState<\/em> e <em>useEffect<\/em> do React;<\/li>\r\n<li>Criamos um estado para guardar os tweets (array vazio como estado inicial);<\/li>\r\n<li>Criamos um efeito que tem a fun\u00e7\u00e3o de buscar os tweets no servidor e guardar no estado do componente;<\/li>\r\n<li>Buscamos cada usu\u00e1rio a partir do owner do tweet para termos acesso ao username.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">* Perceba que a fun\u00e7\u00e3o async foi declarada e chamada dentro do <em>useEffect <\/em>devido ao fato do <em>useEffect <\/em>j\u00e1 ser uma fun\u00e7\u00e3o ass\u00edncrona, devemos fazer a chamada de API desta maneira.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Nosso componente visual deve estar parecido com este:<\/p>\r\n\r\n\r\n\r\n<div class=\"wp-block-image\">\r\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"681\" height=\"366\" class=\"wp-image-9758\" src=\"https:\/\/www.geekhunter.com\/pt\/blog\/wp-content\/uploads\/2020\/03\/componente-visual-da-aplica\u00e7\u00e3o.png\" alt=\"componente visual da aplica\u00e7\u00e3o \" srcset=\"https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/componente-visual-da-aplica\u00e7\u00e3o.png 681w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/componente-visual-da-aplica\u00e7\u00e3o-150x81.png 150w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/componente-visual-da-aplica\u00e7\u00e3o-100x54.png 100w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/componente-visual-da-aplica\u00e7\u00e3o-600x322.png 600w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/componente-visual-da-aplica\u00e7\u00e3o-450x242.png 450w\" sizes=\"(max-width: 681px) 100vw, 681px\" \/><\/figure>\r\n<\/div>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">A falta de estiliza\u00e7\u00e3o se d\u00e1 pelo fato de n\u00e3o termos criado o arquivo <em>styles.js <\/em>para a listagem, e ainda n\u00e3o termos implementado o componente que representar\u00e1 cada tweet.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Criando o componente do tweet<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Criaremos um componente espec\u00edfico para mostrar os tweets na tela, na pasta <em>src\/components\/Tweet<\/em> criamos um novo arquivo <em>index.js <\/em>com o seguinte conte\u00fado:<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/d56197271b4fae365c48d7152f74ff2d.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Renderizamos o componente a partir dos atributos que vieram via <em>props<\/em>, por\u00e9m se nenhuma estiliza\u00e7\u00e3o. Criaremos ent\u00e3o, na pasta <em>src\/components\/Tweet, <\/em>o arquivo <em>styles.js <\/em>como o seguinte c\u00f3digo:<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/956a4886adb8cbd56dd7794af9db51ac.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">E susbituiremos as<em> tags html <\/em>pelos componentes estilizados:<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/8aacc78001c4982b5769c4a641a9cf3a.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">No componente <em>TweetList<\/em> devemos substituir a tag <em>&lt;li&gt;<\/em> pelo componente <em>Tweet<\/em>:<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/a3849dcbba0d255798152ca8e1b6f53d.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Se verificarmos nosso browser, pereceberemos que o atributo referente ao dono do tweet est\u00e1 como um ID. Se quisermos mostrar o nome de quem fez o tweet, devemos buscar no servidor o usu\u00e1rio e salvar no estado o nome do usu\u00e1rio.\u00a0<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Para isto, dentro do componente <em>Tweet<\/em> criaremos uma requisi\u00e7\u00e3o ao banco da seguinte forma:<\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/089573498f7be8d5809d9b9e686fbdaf.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"715\" height=\"808\" class=\"wp-image-9759\" src=\"https:\/\/www.geekhunter.com\/pt\/blog\/wp-content\/uploads\/2020\/03\/projeto-de-desenvolvimento-twitter-1.png\" alt=\"sua vers\u00e3o do twitter \" srcset=\"https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/projeto-de-desenvolvimento-twitter-1.png 715w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/projeto-de-desenvolvimento-twitter-1-133x150.png 133w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/projeto-de-desenvolvimento-twitter-1-88x100.png 88w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/projeto-de-desenvolvimento-twitter-1-531x600.png 531w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/projeto-de-desenvolvimento-twitter-1-398x450.png 398w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/projeto-de-desenvolvimento-twitter-1-478x540.png 478w, https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/projeto-de-desenvolvimento-twitter-1-150x170.png 150w\" sizes=\"(max-width: 715px) 100vw, 715px\" \/><\/figure>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Curtindo um tweet<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">O usu\u00e1rio deve poder curtir os tweets que est\u00e3o na lista de tweets, para isso devemos ter uma fun\u00e7\u00e3o que altera o objeto do tweet no componente <em>Home<\/em>.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Por conven\u00e7\u00e3o, chamamos essa fun\u00e7\u00e3o de <em>onLike <\/em>e passaremos via <em>props <\/em>do componente TweetList e depois para o <em>Tweet<\/em>.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><em>Home.js<\/em><\/p>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/7b7072b00f7b83fa2fe5bbb3b24df8e8.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>Tiramos ou retiramos o tweet de acordo com a a\u00e7\u00e3o:\r\n<ul>\r\n<li>Caso j\u00e1 esteja curtido, removemos;<\/li>\r\n<li>Caso n\u00e3o esteja curtido, adicionamos;<\/li>\r\n<\/ul>\r\n<\/li>\r\n<li>Passamos a fun\u00e7\u00e3o de onLike para o tweetList.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/geekhunterbr\/754f87eb056f916a4bd950da3f4e4638.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">O que acharam desse React tutorial?<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Com isso terminamos as funcionalidades da nossa aplica\u00e7\u00e3o, implementamos:<\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>Login;<\/li>\r\n<li>Registro;<\/li>\r\n<li>Cria\u00e7\u00e3o de tweets;<\/li>\r\n<li>Listagem de tweets;<\/li>\r\n<li>Likes.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Espero que tenha conseguido passar um pouco do meu conhecimento com essas tecnologias, o c\u00f3digo tem bastante partes que pode ser melhorado e otimizado ainda para que seja uma aplica\u00e7\u00e3o poss\u00edvel de ir para produ\u00e7\u00e3o.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Fico \u00e0 disposi\u00e7\u00e3o para tirar qualquer d\u00favida e segue o <strong><a href=\"https:\/\/github.com\/picolloo\/twitter-app\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"reposit\u00f3rio github (abre numa nova aba)\">reposit\u00f3rio github<\/a><\/strong> usado no desenvolvimento.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">At\u00e9 mais! \ud83d\ude09<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.geekhunter.com\/pt\/vagas\" target=\"_blank\" rel=\"noreferrer noopener\"><img decoding=\"async\" class=\"wp-image-9728\" src=\"https:\/\/www.geekhunter.com\/pt\/blog\/wp-content\/uploads\/2020\/03\/Vagas-React-1024x336.png\" alt=\"\" \/><\/a><\/figure>\r\n","protected":false},"excerpt":{"rendered":"<p>React tutorial? Deixa comigo! \ud83d\ude00 Nesta parte 2 da nossa aplica\u00e7\u00e3o full-stack iremos criar um clone do Twitter de ponta a ponta! Caso n\u00e3o tenha visto a parte 1, criamos o servidor utilizando Node JS Express. Voc\u00ea tamb\u00e9m pode acessar o c\u00f3digo completo no GitHub, deste e do artigo anterior. Voc\u00ea tamb\u00e9m pode fazer apenas [&hellip;]<\/p>\n","protected":false},"author":167,"featured_media":9717,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[18],"tags":[],"class_list":["post-9694","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-desenvolvimiento-de-software"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v28.6 (Yoast SEO v28.6) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>React tutorial: clonar o Twitter com uma aplica\u00e7\u00e3o fullstack?<\/title>\n<meta name=\"description\" content=\"Com esse React Tutorial voc\u00ea vai saber como clonar o Twitter! Isso mesmo! Um passo a passo para voc\u00ea criar uma aplica\u00e7\u00e3o fullstack!\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.geekhunter.com\/pt\/blog\/twitter-clone-full-stack-app-parte-2-react-tutorial\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Twitter Clone full stack app \u2013 Parte 2: React tutorial\" \/>\n<meta property=\"og:description\" content=\"React tutorial? Deixa comigo! :D Nesta parte 2 da nossa aplica\u00e7\u00e3o full-stack iremos criar um clone do Twitter de ponta a ponta! Caso n\u00e3o tenha visto a\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.geekhunter.com\/pt\/blog\/twitter-clone-full-stack-app-parte-2-react-tutorial\/\" \/>\n<meta property=\"og:site_name\" content=\"Blog Geekhunter\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/geekhunterbr\/\" \/>\n<meta property=\"article:published_time\" content=\"2020-03-24T20:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-10-29T19:46:49+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/React-tutorial.png\" \/>\n\t<meta property=\"og:image:width\" content=\"750\" \/>\n\t<meta property=\"og:image:height\" content=\"410\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Geekhunter\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@geekhunterbr\" \/>\n<meta name=\"twitter:site\" content=\"@geekhunterbr\" \/>\n<meta name=\"twitter:label1\" content=\"Escrito por\" \/>\n\t<meta name=\"twitter:data1\" content=\"Geekhunter\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. tempo de leitura\" \/>\n\t<meta name=\"twitter:data2\" content=\"30 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.geekhunter.com\\\/pt\\\/blog\\\/twitter-clone-full-stack-app-parte-2-react-tutorial\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.geekhunter.com\\\/pt\\\/blog\\\/twitter-clone-full-stack-app-parte-2-react-tutorial\\\/\"},\"author\":{\"name\":\"Geekhunter\",\"@id\":\"https:\\\/\\\/www.geekhunter.com\\\/pt\\\/blog\\\/#\\\/schema\\\/person\\\/9f62b173345139f7bbdaf55312c3d400\"},\"headline\":\"Twitter Clone full stack app \u2013 Parte 2: React tutorial\",\"datePublished\":\"2020-03-24T20:00:00+00:00\",\"dateModified\":\"2024-10-29T19:46:49+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.geekhunter.com\\\/pt\\\/blog\\\/twitter-clone-full-stack-app-parte-2-react-tutorial\\\/\"},\"wordCount\":4917,\"publisher\":{\"@id\":\"https:\\\/\\\/www.geekhunter.com\\\/pt\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.geekhunter.com\\\/pt\\\/blog\\\/twitter-clone-full-stack-app-parte-2-react-tutorial\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.geekhunter.com/pt/blog\\\/wp-content\\\/uploads\\\/2020\\\/03\\\/React-tutorial.png\",\"articleSection\":[\"Desenvolvimiento de software\"],\"inLanguage\":\"pt-BR\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.geekhunter.com\\\/pt\\\/blog\\\/twitter-clone-full-stack-app-parte-2-react-tutorial\\\/\",\"url\":\"https:\\\/\\\/www.geekhunter.com\\\/pt\\\/blog\\\/twitter-clone-full-stack-app-parte-2-react-tutorial\\\/\",\"name\":\"React tutorial: clonar o Twitter com uma aplica\u00e7\u00e3o fullstack?\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.geekhunter.com\\\/pt\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.geekhunter.com\\\/pt\\\/blog\\\/twitter-clone-full-stack-app-parte-2-react-tutorial\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.geekhunter.com\\\/pt\\\/blog\\\/twitter-clone-full-stack-app-parte-2-react-tutorial\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.geekhunter.com/pt/blog\\\/wp-content\\\/uploads\\\/2020\\\/03\\\/React-tutorial.png\",\"datePublished\":\"2020-03-24T20:00:00+00:00\",\"dateModified\":\"2024-10-29T19:46:49+00:00\",\"description\":\"Com esse React Tutorial voc\u00ea vai saber como clonar o Twitter! Isso mesmo! Um passo a passo para voc\u00ea criar uma aplica\u00e7\u00e3o fullstack!\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.geekhunter.com\\\/pt\\\/blog\\\/twitter-clone-full-stack-app-parte-2-react-tutorial\\\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.geekhunter.com/pt/blog\\\/twitter-clone-full-stack-app-parte-2-react-tutorial\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\\\/\\\/www.geekhunter.com\\\/pt\\\/blog\\\/twitter-clone-full-stack-app-parte-2-react-tutorial\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.geekhunter.com\\\/pt\\\/blog\\\/wp-content\\\/uploads\\\/2020\\\/03\\\/React-tutorial.png\",\"contentUrl\":\"https:\\\/\\\/www.geekhunter.com/pt/blog\\\/wp-content\\\/uploads\\\/2020\\\/03\\\/React-tutorial.png\",\"width\":750,\"height\":410,\"caption\":\"React tutorial\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.geekhunter.com\\\/pt\\\/blog\\\/twitter-clone-full-stack-app-parte-2-react-tutorial\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"In\u00edcio\",\"item\":\"https:\\\/\\\/www.geekhunter.com/pt/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Mundo TI\",\"item\":\"https:\\\/\\\/www.geekhunter.com/pt/blog\\\/category\\\/mundo-ti\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Desenvolvimiento de software\",\"item\":\"https:\\\/\\\/www.geekhunter.com/pt/blog\\\/category\\\/mundo-ti\\\/desenvolvimiento-de-software\\\/\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Twitter Clone full stack app \u2013 Parte 2: React tutorial\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.geekhunter.com\\\/pt\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.geekhunter.com\\\/pt\\\/blog\\\/\",\"name\":\"Blog de TI\",\"description\":\"Dicas para o RH e profissionais da \u00e1rea TI\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.geekhunter.com\\\/pt\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.geekhunter.com/pt/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"pt-BR\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.geekhunter.com\\\/pt\\\/blog\\\/#organization\",\"name\":\"GeekHunter\",\"url\":\"https:\\\/\\\/www.geekhunter.com\\\/pt\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\\\/\\\/www.geekhunter.com\\\/pt\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.geekhunter.com\\\/pt\\\/blog\\\/wp-content\\\/uploads\\\/2024\\\/10\\\/icon-1.png\",\"contentUrl\":\"https:\\\/\\\/www.geekhunter.com/pt/blog\\\/wp-content\\\/uploads\\\/2024\\\/10\\\/icon-1.png\",\"width\":300,\"height\":300,\"caption\":\"GeekHunter\"},\"image\":{\"@id\":\"https:\\\/\\\/www.geekhunter.com\\\/pt\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/geekhunterbr\\\/\",\"https:\\\/\\\/x.com\\\/geekhunterbr\",\"https:\\\/\\\/www.instagram.com\\\/geekhunterbr\\\/\",\"https:\\\/\\\/www.linkedin.com\\\/company\\\/geekhunter-brasil\\\/\",\"https:\\\/\\\/www.youtube.com\\\/@GeekHunterOfficial\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.geekhunter.com\\\/pt\\\/blog\\\/#\\\/schema\\\/person\\\/9f62b173345139f7bbdaf55312c3d400\",\"name\":\"Geekhunter\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/09a0f76de8cf1fa3621f8b73417ce43344b42e1324a07a9af24f57c5eef49840?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/09a0f76de8cf1fa3621f8b73417ce43344b42e1324a07a9af24f57c5eef49840?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/09a0f76de8cf1fa3621f8b73417ce43344b42e1324a07a9af24f57c5eef49840?s=96&d=mm&r=g\",\"caption\":\"Geekhunter\"},\"url\":\"https:\\\/\\\/www.geekhunter.com\\\/pt\\\/blog\\\/author\\\/matias\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"React tutorial: clonar o Twitter com uma aplica\u00e7\u00e3o fullstack?","description":"Com esse React Tutorial voc\u00ea vai saber como clonar o Twitter! Isso mesmo! Um passo a passo para voc\u00ea criar uma aplica\u00e7\u00e3o fullstack!","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.geekhunter.com\/pt\/blog\/twitter-clone-full-stack-app-parte-2-react-tutorial\/","og_locale":"pt_BR","og_type":"article","og_title":"Twitter Clone full stack app \u2013 Parte 2: React tutorial","og_description":"React tutorial? Deixa comigo! :D Nesta parte 2 da nossa aplica\u00e7\u00e3o full-stack iremos criar um clone do Twitter de ponta a ponta! Caso n\u00e3o tenha visto a","og_url":"https:\/\/www.geekhunter.com\/pt\/blog\/twitter-clone-full-stack-app-parte-2-react-tutorial\/","og_site_name":"Blog Geekhunter","article_publisher":"https:\/\/www.facebook.com\/geekhunterbr\/","article_published_time":"2020-03-24T20:00:00+00:00","article_modified_time":"2024-10-29T19:46:49+00:00","og_image":[{"width":750,"height":410,"url":"https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/React-tutorial.png","type":"image\/png"}],"author":"Geekhunter","twitter_card":"summary_large_image","twitter_creator":"@geekhunterbr","twitter_site":"@geekhunterbr","twitter_misc":{"Escrito por":"Geekhunter","Est. tempo de leitura":"30 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.geekhunter.com\/pt\/blog\/twitter-clone-full-stack-app-parte-2-react-tutorial\/#article","isPartOf":{"@id":"https:\/\/www.geekhunter.com\/pt\/blog\/twitter-clone-full-stack-app-parte-2-react-tutorial\/"},"author":{"name":"Geekhunter","@id":"https:\/\/www.geekhunter.com\/pt\/blog\/#\/schema\/person\/9f62b173345139f7bbdaf55312c3d400"},"headline":"Twitter Clone full stack app \u2013 Parte 2: React tutorial","datePublished":"2020-03-24T20:00:00+00:00","dateModified":"2024-10-29T19:46:49+00:00","mainEntityOfPage":{"@id":"https:\/\/www.geekhunter.com\/pt\/blog\/twitter-clone-full-stack-app-parte-2-react-tutorial\/"},"wordCount":4917,"publisher":{"@id":"https:\/\/www.geekhunter.com\/pt\/blog\/#organization"},"image":{"@id":"https:\/\/www.geekhunter.com\/pt\/blog\/twitter-clone-full-stack-app-parte-2-react-tutorial\/#primaryimage"},"thumbnailUrl":"https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/React-tutorial.png","articleSection":["Desenvolvimiento de software"],"inLanguage":"pt-BR"},{"@type":"WebPage","@id":"https:\/\/www.geekhunter.com\/pt\/blog\/twitter-clone-full-stack-app-parte-2-react-tutorial\/","url":"https:\/\/www.geekhunter.com\/pt\/blog\/twitter-clone-full-stack-app-parte-2-react-tutorial\/","name":"React tutorial: clonar o Twitter com uma aplica\u00e7\u00e3o fullstack?","isPartOf":{"@id":"https:\/\/www.geekhunter.com\/pt\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.geekhunter.com\/pt\/blog\/twitter-clone-full-stack-app-parte-2-react-tutorial\/#primaryimage"},"image":{"@id":"https:\/\/www.geekhunter.com\/pt\/blog\/twitter-clone-full-stack-app-parte-2-react-tutorial\/#primaryimage"},"thumbnailUrl":"https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/React-tutorial.png","datePublished":"2020-03-24T20:00:00+00:00","dateModified":"2024-10-29T19:46:49+00:00","description":"Com esse React Tutorial voc\u00ea vai saber como clonar o Twitter! Isso mesmo! Um passo a passo para voc\u00ea criar uma aplica\u00e7\u00e3o fullstack!","breadcrumb":{"@id":"https:\/\/www.geekhunter.com\/pt\/blog\/twitter-clone-full-stack-app-parte-2-react-tutorial\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.geekhunter.com/pt/blog\/twitter-clone-full-stack-app-parte-2-react-tutorial\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.geekhunter.com\/pt\/blog\/twitter-clone-full-stack-app-parte-2-react-tutorial\/#primaryimage","url":"https:\/\/www.geekhunter.com\/pt\/blog\/wp-content\/uploads\/2020\/03\/React-tutorial.png","contentUrl":"https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2020\/03\/React-tutorial.png","width":750,"height":410,"caption":"React tutorial"},{"@type":"BreadcrumbList","@id":"https:\/\/www.geekhunter.com\/pt\/blog\/twitter-clone-full-stack-app-parte-2-react-tutorial\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"In\u00edcio","item":"https:\/\/www.geekhunter.com/pt/blog\/"},{"@type":"ListItem","position":2,"name":"Mundo TI","item":"https:\/\/www.geekhunter.com/pt/blog\/category\/mundo-ti\/"},{"@type":"ListItem","position":3,"name":"Desenvolvimiento de software","item":"https:\/\/www.geekhunter.com/pt/blog\/category\/mundo-ti\/desenvolvimiento-de-software\/"},{"@type":"ListItem","position":4,"name":"Twitter Clone full stack app \u2013 Parte 2: React tutorial"}]},{"@type":"WebSite","@id":"https:\/\/www.geekhunter.com\/pt\/blog\/#website","url":"https:\/\/www.geekhunter.com\/pt\/blog\/","name":"Blog de TI","description":"Dicas para o RH e profissionais da \u00e1rea TI","publisher":{"@id":"https:\/\/www.geekhunter.com\/pt\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.geekhunter.com/pt/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"pt-BR"},{"@type":"Organization","@id":"https:\/\/www.geekhunter.com\/pt\/blog\/#organization","name":"GeekHunter","url":"https:\/\/www.geekhunter.com\/pt\/blog\/","logo":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.geekhunter.com\/pt\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.geekhunter.com\/pt\/blog\/wp-content\/uploads\/2024\/10\/icon-1.png","contentUrl":"https:\/\/www.geekhunter.com/pt/blog\/wp-content\/uploads\/2024\/10\/icon-1.png","width":300,"height":300,"caption":"GeekHunter"},"image":{"@id":"https:\/\/www.geekhunter.com\/pt\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/geekhunterbr\/","https:\/\/x.com\/geekhunterbr","https:\/\/www.instagram.com\/geekhunterbr\/","https:\/\/www.linkedin.com\/company\/geekhunter-brasil\/","https:\/\/www.youtube.com\/@GeekHunterOfficial"]},{"@type":"Person","@id":"https:\/\/www.geekhunter.com\/pt\/blog\/#\/schema\/person\/9f62b173345139f7bbdaf55312c3d400","name":"Geekhunter","image":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/secure.gravatar.com\/avatar\/09a0f76de8cf1fa3621f8b73417ce43344b42e1324a07a9af24f57c5eef49840?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/09a0f76de8cf1fa3621f8b73417ce43344b42e1324a07a9af24f57c5eef49840?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/09a0f76de8cf1fa3621f8b73417ce43344b42e1324a07a9af24f57c5eef49840?s=96&d=mm&r=g","caption":"Geekhunter"},"url":"https:\/\/www.geekhunter.com\/pt\/blog\/author\/matias\/"}]}},"_links":{"self":[{"href":"https:\/\/www.geekhunter.com/pt/blog\/wp-json\/wp\/v2\/posts\/9694","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.geekhunter.com/pt/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.geekhunter.com/pt/blog\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/www.geekhunter.com/pt/blog\/wp-json\/wp\/v2\/comments?post=9694"}],"version-history":[{"count":0,"href":"https:\/\/www.geekhunter.com/pt/blog\/wp-json\/wp\/v2\/posts\/9694\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.geekhunter.com/pt/blog\/wp-json\/wp\/v2\/media\/9717"}],"wp:attachment":[{"href":"https:\/\/www.geekhunter.com/pt/blog\/wp-json\/wp\/v2\/media?parent=9694"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.geekhunter.com/pt/blog\/wp-json\/wp\/v2\/categories?post=9694"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.geekhunter.com/pt/blog\/wp-json\/wp\/v2\/tags?post=9694"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}