Olá, bem-vindas e bem-vindos! Eu continuo sendo o Careca Barbudo, sua pessoa amiga. Este curso é uma continuação direta do curso no qual desenvolvemos o aplicativo de Pomodoro, Focus.
Agora, vamos deixar esse aplicativo de lado e utilizar outra aplicação. Nós vamos desenvolver uma rede social para pessoas que gostam de correr.
Para chegar a esse resultado, precisaremos lidar com o início de sessão de pessoas usuárias, isto é, login (início de sessão) e cadastro. Precisaremos cadastrar pessoas usuárias e iniciar suas sessões.
Também teremos comunicação com o back-end (camada de servidor): como nos comunicamos com o back-end dentro do ecossistema do React, qual é a abordagem antiga, qual é a abordagem nova, quando utilizar cada uma e qual estilo adotar em cada momento.
Nós poderemos adicionar comentários; o recurso de comentários estará disponível, o que nos permitirá interagir com todas as publicações. Teremos várias páginas para navegação, incluindo uma página de perfil, e enviaremos imagens.
Há diversas funcionalidades interessantes para consolidar e ampliar nosso conjunto de ferramentas do ecossistema do React.
Para chegar lá, partiremos de um projeto base que já tem todo o layout (estrutura visual) pronto, mas sem comportamento, e nós o evoluiremos. Aprenderemos como fazer a navegação e como nos comunicamos com o back-end (camada de servidor). E, falando em back-end, colocaremos um back-end do zero. Não vamos construí-lo; nós o receberemos pronto da equipe de back-end, mas aprenderemos a ler documentação e a colocar um projeto em execução. Há mais de uma forma de executar esse back-end. Você verá tudo isso conosco a partir do próximo vídeo, porque eu já estou lá esperando por você.
Um forte abraço e nos vemos por aí.
Como diria o ditado: bem começado é meio caminho andado. Antes de entrarmos no conteúdo novo, isto é, nas funcionalidades novas do React que vamos explorar neste curso, o primeiro passo é analisar o projeto base e entender por que desta vez não vamos começar do zero criando um projeto com Vite.
Já baixamos o projeto para nossa máquina. As instruções de como fazer isso estão em "Preparando o ambiente". Podemos clonar a partir do GitHub ou fazer o download do arquivo zip (arquivo compactado), abrir a pasta e seguir em frente. No nosso caso, o projeto já está em uma pasta no desktop chamada "Runner Circle", que é o nome do projeto. Vamos entrar nessa pasta e abrir o VS Code. Estamos realizando tudo pelo terminal, mas é possível fazer manualmente: ao abrir o VS Code, podemos acessar o menu File/Arquivo e escolher a opção Open Folder/Abrir pasta.
A base deste projeto é exatamente o que precisamos para detalhar e desenvolver as funcionalidades novas do React que vamos aprender. Seu core (núcleo) continua o mesmo: é um projeto Vite usando React e TypeScript.
Antes de olharmos o código, vamos vê-lo funcionando. No terminal, vamos executar npm i para instalar as dependências. O comando indicou, por acaso, que há três vulnerabilidades: uma moderada e uma alta. Para resolver, executamos npm audit fix. Essa é uma boa prática. Vamos ver se resolve. Perfeito, resolveu. Agora há zero vulnerabilidades. Isso é muito comum acontecer. Entre a publicação do projeto, a gravação do curso e o momento em que você executa, podem aparecer outras, e já sabemos como resolver. O npm audit fix identifica as vulnerabilidades conhecidas das versões em uso. No nosso caso, todas estavam em dependências de nossas dependências, bem no fundo da árvore, mas o processo conseguiu resolver e atualizar as versões necessárias. Note que o arquivo package-lock.json já foi modificado.
Com a base instalada, em vez de usar o terminal do VS Code, que fechamos e abrimos com frequência, vamos voltar ao terminal do sistema e executar npm run dev, que inicia a aplicação. Assim, ela fica disponível em localhost:5173.
Ao carregar, foi renderizada uma página de cadastro. O preenchimento exibido é o preenchimento automático do Chrome de dados já utilizados anteriormente. Ao realizar scroll (rolagem) para baixo, é exibida a página de login (entrada). Com mais um scroll (rolagem), aparece uma página de feed (linha do tempo), onde há publicações. Runner Circle é uma grande rede social para pessoas que apreciam correr. Já há um feed (linha do tempo) aqui; tudo está simulado e todos os cards são iguais, mas estão presentes. Também há uma página para criar uma nova publicação, ou seja, enviar e publicar uma corrida realizada. Há ainda a página de perfil, que mostra nossas publicações e nossos likes. Além disso, há a página de edição de perfil. E termina por aqui.
Todas as páginas estão empilhadas, uma em cima da outra. Isso ocorre porque vamos detalhar e adicionar funcionalidades. Neste momento, é apenas o layout.
Agora que vimos tudo funcionando, podemos olhar o código-fonte. Ao abrir a pasta "src", temos duas pastas separadas aqui dentro desta vez. A pasta "components" segue a mesma estrutura usada no curso anterior. Dentro de "components", há vários componentes pequenos: formulário, ações do formulário, campo do formulário, ícones, placeholder (marca de posição) de imagem e o ImageUploader, que é o componente exibido anteriormente. Na verdade, sabemos isso de memória.
É este componente aqui, onde está a opção de enviar imagens. Existem os seguintes componentes:
São todos componentes. Não vamos detalhá-los um a um. Vamos abrir um ao acaso: o textarea. Eles seguem a mesma estrutura que usamos no curso anterior. É um componente comum, com props devidamente tipadas.
Nesse cenário, usamos ComponentProps. Importamos ComponentProps de React e definimos que o textarea aceita qualquer propriedade que um elemento HTML textarea aceitaria. Em seguida, repassamos todas as propriedades recebidas para o elemento HTML. O TypeScript sabe o que o textarea aceita e o que não aceita.
Para ilustrar exatamente isso no código do projeto, o componente Textarea está implementado assim:
import type { ComponentProps } from 'react'
import styles from './Textarea.module.css'
type TextareaProps = ComponentProps<'textarea'>
function Textarea({ ...rest }: TextareaProps) {
return <textarea className={styles.textarea} {...rest} />
}
export default Textarea
Esse componente tipa suas propriedades com ComponentProps<'textarea'>, permitindo passar qualquer prop válida de um <textarea> nativo, enquanto aplica um estilo próprio via CSS Modules.
Todo o projeto segue essa mesma estrutura. Quanto aos estilos, fazemos o mesmo que no curso anterior, utilizando CSS Modules. Portanto, no nível de componente, não há nada novo: é apenas layout, com TypeScript e props devidamente tipadas.
Para completar a visão, o arquivo de estilos CSS Module associado ao Textarea define a aparência do campo:
.textarea {
width: 100%;
min-height: 7.5rem;
padding: 0.75rem 1rem;
border: none;
border-radius: 8px;
background-color: var(--gray-input);
font-size: 1rem;
resize: none;
}
.textarea::placeholder {
color: var(--text);
opacity: 0.8;
}
.textarea:focus {
outline: 2px solid var(--dark);
}
O que há de diferente? Esta parte que chamamos de "pages", que são as páginas:
Register (página de registro),Profile (página de perfil),NewPost (para registrar uma nova corrida que a pessoa realizou),Login (página de login),Feed (página de feed),EditProfile (página de edição de perfil).A parte de layout está toda pronta. O que precisamos fazer é implementar comportamento. Se lembrarmos, no curso anterior começamos um projeto do zero, e uma das aulas foi dedicada apenas ao layout, ou seja, a codificar componentes. Trouxemos os componentes do nosso aplicativo Focus. Neste curso, desta vez, o projeto está começando do zero.
Você pode se aprofundar. Você pode usar um agente de IA e pedir que explique os componentes e todo o restante, se desejar. Fique à vontade. Por ora, isto é o que precisamos saber antes de começar.
Antes de começar, há uma última coisa que queremos mostrar. No navegador, vamos abrir o Developer Tools e a aba Console. Na Console, há uma mensagem dizendo: “Se quiser uma melhor experiência de desenvolvimento, experimente React DevTools”. Vamos clicar nesse link. Ele nos leva a uma página que explica o que o Developer Tools faz, como funciona, as diferentes extensões para os diversos navegadores e os recursos interessantes que oferece. Vamos abrir a página de instalação no Chrome e adicionar a extensão. Pronto. Ela já foi habilitada e aparece no canto superior direito.
Agora, no Runner Circle, vamos verificar se já aparece. Já está aqui. Como acabamos de instalá-la, vamos fechar o navegador, abri-lo novamente e acessar localhost:5173. Ao olhar as extensões, percebemos que antes a extensão do Developer Tools estava cinza; agora está vermelha. Portanto, foi identificada.
Onde ela aparece? No Developer Tools. Nas abas em que temos Elements, Console e assim por diante, podemos abri-la. Agora temos Components. Esse painel Components vai carregar e ler todos os componentes React. Tudo o que fizermos, tudo o que for acontecendo, aparecerá ali. Vale a pena deixar essa extensão ativa. Eventualmente, voltaremos a consultá-la.
Com tudo pronto e no lugar, vamos começar a desenvolver e decompor esta aplicação que tem todas essas páginas empilhadas. Precisamos começar a criar uma navegação entre elas. Esse tema é do próximo vídeo.
Qual é o problema que queremos resolver agora? Neste momento, nossas páginas estão todas empilhadas. O que gostaríamos que acontecesse? Queremos exibir apenas a página de cadastro quando alguém acessa a URL /cadastro. Queremos que apenas a página de cadastro seja mostrada conforme a URL; ou seja, em /login, /feed, /home ou na raiz do projeto (a página inicial), exibir o feed. É isso que desejamos: não exibir as páginas empilhadas.
Para visualizar o cenário atual, veja como o App está renderizando todas as páginas de forma empilhada:
import Register from './pages/Register'
import Login from './pages/Login'
import Feed from './pages/Feed'
import NewPost from './pages/NewPost'
import Profile from './pages/Profile'
import EditProfile from './pages/EditProfile'
function App() {
return (
<>
<Register />
<Login />
<Feed />
<NewPost />
<Profile />
<EditProfile />
</>
)
}
Podemos abrir nosso App e acessar a propriedade global window.location. Em window.location existem várias propriedades, e uma delas é pathname, que indica qual é a URL, o caminho que estamos acessando. Podemos usar window.location.pathname. Se temos acesso à URL (o que vem depois de localhost:5173, ou seja, o recurso que estamos acessando), podemos ir ao VS Code e escrever um if. Não no index, e sim em nosso app.tsx. Podemos escrever um if mais extenso. Por exemplo, definir const url = window.location.pathname:
import Register from './pages/Register'
import Login from './pages/Login'
import Feed from './pages/Feed'
import NewPost from './pages/NewPost'
import Profile from './pages/Profile'
import EditProfile from './pages/EditProfile'
function App() {
const url = window.location.pathname;
return (
<>
<Register />
<Login />
<Feed />
<NewPost />
<Profile />
<EditProfile />
</>
)
}
Em seguida, verificar com um if se url === '/cadastro' para retornar nossa página de cadastro:
import Register from './pages/Register'
import Login from './pages/Login'
import Feed from './pages/Feed'
import NewPost from './pages/NewPost'
import Profile from './pages/Profile'
import EditProfile from './pages/EditProfile'
function App() {
const url = window.location.pathname;
if (url === '/cadastro') {
return <Register />
}
return (
<>
<Register />
<Login />
<Feed />
<NewPost />
<Profile />
<EditProfile />
</>
)
}
Ao recarregar, percebemos que não há mais aquele loop infinito; apenas a página de cadastro é exibida.
Entretanto, imaginemos o caos que isso se tornaria. Como adicionaríamos muitas páginas se estivermos controlando tudo manualmente? Esse é um enfoque imperativo. O React propõe um enfoque declarativo. Em vez de implementarmos tudo manualmente dessa forma, vamos usar uma biblioteca muito conhecida, focada em roteamento em aplicações React: React Router. Ela possui três modos distintos de operação: Framework (estrutura), Data (dados) e Declarativo. No curso, utilizaremos o modo Declarativo. Deixaremos uma atividade para aprofundamento, para que você entenda a diferença entre esses modos e, se desejar, experimente-os ao longo do tempo. Por ora, durante o curso, utilizaremos a forma Declarativa.
Em reactrouter.com, ao acessarmos o site, podemos ir para a página de docs (documentação) por meio de um botão. No menu à esquerda há uma lista extensa de tópicos. Ela começa pelo modo Framework (estrutura), depois apresenta o modo Data (dados) e, ao final, o modo Declarative (declarativo). Logo abaixo de Declarative (declarativo) está Installation (instalação). Lá é indicado que podemos instalar a partir de um modelo de React, se quisermos, ou instalar diretamente no projeto usando o comando npm i react-router. É isso que faremos: instalar com npm i react-router.
Abrimos o terminal do VS Code e realizamos a instalação com:
npm i react-router
Em seguida, serão apresentadas algumas regras para que nossa aplicação funcione corretamente. A primeira instrução é: precisamos de um BrowserRouter.
A documentação sugere realizar a configuração no arquivo main.tsx. Vamos seguir essa indicação: no projeto, abrimos o main.tsx e, ao redor do App, envolvemos com o BrowserRouter. Primeiro, veja como está o main.tsx antes da alteração:
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.tsx'
createRoot(document.getElementById('root')!).render(
<StrictMode>
<App />
</StrictMode>,
)
Agora, envolvemos o App com o BrowserRouter:
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.tsx'
createRoot(document.getElementById('root')!).render(
<StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</StrictMode>,
)
Por fim, garantimos que o BrowserRouter seja importado:
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.tsx'
import { BrowserRouter } from 'react-router'
createRoot(document.getElementById('root')!).render(
<StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</StrictMode>,
)
A partir do momento em que fazemos essa alteração, isso não deve quebrar a aplicação nem alterar seu comportamento. Fomos ao RunnerCircle e está tudo correto.
Agora temos nossa extensão para observar. Nela, foi colocado um BrowserRouter na parte superior e adicionados vários elementos no meio:
BrowserRouterRouter Navigation ProviderLocation ProviderTudo isso é do React Router; não precisamos compreender ainda o que cada um faz. Em seguida, a execução entra no nosso App, registra e começa a exibir Auto Layout, Login, Feed, New Post, New Profile e Edit Profile. Também é indicado que algumas páginas estão memorizadas, o que se relaciona ao React Compiler que vimos no curso anterior.
Com isso instalado, o próximo passo é configurar o roteamento, isto é, começar a declarar nossas regras.
Dentro do BrowserRouter, precisamos trazer o elemento Routes (no plural). Ou seja, dentro do BrowserRouter não vamos mais renderizar o App diretamente; vamos utilizar o componente Routes para declarar quais serão nossas rotas, podendo definir várias. Primeiro, adicionamos o contêiner Routes:
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.tsx'
import { BrowserRouter } from 'react-router'
createRoot(document.getElementById('root')!).render(
<StrictMode>
<BrowserRouter>
<Routes>
</Routes>
</BrowserRouter>
</StrictMode>,
)
Copiamos e colamos a sintaxe para facilitar e pedimos ao VS Code que importe o elemento Route (no singular). Inicialmente, declaramos uma rota para '/' apontando para o App:
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.tsx'
import { BrowserRouter } from 'react-router'
createRoot(document.getElementById('root')!).render(
<StrictMode>
<BrowserRouter>
<Routes>
<Route path="/" element={<App />} />
</Routes>
</BrowserRouter>
</StrictMode>,
)
Em seguida, deixamos os imports corretos para Route e Routes:
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.tsx'
import { BrowserRouter, Route, Routes } from 'react-router'
createRoot(document.getElementById('root')!).render(
<StrictMode>
<BrowserRouter>
<Routes>
<Route path="/" element={<App />} />
</Routes>
</BrowserRouter>
</StrictMode>,
)
Seguindo a lógica proposta:
'/', queremos mostrar a página Feed. Importamos Feed e, com isso, não precisamos mais renderizar o App.import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.tsx'
import { BrowserRouter, Route, Routes } from 'react-router'
import Feed from './pages/Feed/index.tsx'
createRoot(document.getElementById('root')!).render(
<StrictMode>
<BrowserRouter>
<Routes>
<Route path="/" element={<Feed />} />
</Routes>
</BrowserRouter>
</StrictMode>,
)
/cadastro, utilizando a página Register. Primeiro, declaramos a rota:import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.tsx'
import { BrowserRouter, Route, Routes } from 'react-router'
import Feed from './pages/Feed/index.tsx'
createRoot(document.getElementById('root')!).render(
<StrictMode>
<BrowserRouter>
<Routes>
<Route path="/" element={<Feed />} />
<Route path="/cadastro" element={<Register />} />
</Routes>
</BrowserRouter>
</StrictMode>,
)
E, por fim, garantimos a importação de Register:
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import { BrowserRouter, Route, Routes } from 'react-router'
import Feed from './pages/Feed/index.tsx'
import Register from './pages/Register/index.tsx'
createRoot(document.getElementById('root')!).render(
<StrictMode>
<BrowserRouter>
<Routes>
<Route path="/" element={<Feed />} />
<Route path="/cadastro" element={<Register />} />
</Routes>
</BrowserRouter>
</StrictMode>,
)
Dessa forma, declaramos nosso roteamento:
'/', mostramos Feed./cadastro, mostramos Register.Nosso código-fonte está sempre em inglês, mas as rotas e as URLs ficarão em português para serem mais amigáveis para a pessoa usuária. Embora o código-fonte permaneça em inglês, estamos escrevendo exclusivamente para pessoas falantes de português. Por isso, vemos este 'cadastro' no meio de diversas palavras em inglês.
Ao voltar para a aplicação, já estávamos apontando para /cadastro e tudo está correto: a árvore de componentes agora exibe apenas Register. Se acessarmos a URL inicial, a aplicação mostrará Feed. Essa página exibe todos os posts.
Temos, assim, uma navegação básica em funcionamento. Na sequência, vamos continuar explorando o React Router e adicionando mais funcionalidades.
Até a próxima!
O curso React: construa uma aplicação front-end completa possui 303 minutos de vídeos, em um total de 69 atividades. Gostou? Conheça nossos outros cursos de React em Front-end, ou leia nossos artigos de Front-end.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
O Plano Plus evoluiu: agora com Luri para impulsionar sua carreira com os melhores cursos e acesso à maior comunidade tech.
2 anos de Alura
Matricule-se no plano PLUS 24 e garanta:
Jornada de estudos progressiva que te guia desde os fundamentos até a atuação prática. Você acompanha sua evolução, entende os próximos passos e se aprofunda nos conteúdos com quem é referência no mercado.
Back-end, Dados, Front-end, DevOps, Mobile, Gestão & Negócios, UX & Design, Cibersegurança, Cloud, Inteligência Artificial
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
Acesso à inteligência artificial da Alura.
No Discord, você participa de eventos exclusivos, pode tirar dúvidas em estudos colaborativos e ainda conta com mentorias em grupo com especialistas de diversas áreas.
Catálogo de tecnologia para quem é da área de Marketing
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
20% de desconto na Pós Tech
Luri Vision chegou no Plano Pro: a IA da Alura que enxerga suas dúvidas, acelera seu aprendizado e conta também com o Alura Língua que prepara você para competir no mercado internacional.
2 anos de Alura
Todos os benefícios do PLUS 24 e mais vantagens exclusivas:
Acesso ao catálogo da Casa do Código e leitura dentro da plataforma
Chat, busca, exercícios abertos, revisão de aula, geração de legenda para certificado.
Modo entrevista - Pratique situações reais e evolua com feedback personalizado
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Para quem quer atingir seus objetivos mais rápido: Luri Vision ilimitado, vagas de emprego exclusivas e mentorias para acelerar cada etapa da jornada.
2 anos de Alura
Todos os benefícios do PRO 24 e mais vantagens exclusivas:
Lives CareerUp: eventos exclusivos com foco em empregabilidade e carreira
Mentorias de carreira: 2 encontros individuais com mentores do Talent Lab
Conecte-se ao mercado com mentoria individual personalizada, vagas exclusivas e networking estratégico que impulsionam sua carreira tech para o próximo nível.