Alura > Cursos de Front-end > Cursos de React > Conteúdos de React > Primeiras aulas do curso React: construa uma aplicação front-end completa

React: construa uma aplicação front-end completa

Explorando o React Router - Apresentação

Apresentando a continuação do curso

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.

Definindo objetivos técnicos iniciais

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.

Detalhando funcionalidades da aplicação

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.

Preparando o projeto base e convidando para o próximo vídeo

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í.

Explorando o React Router - Explorando o código que recebemos

Contextualizando o projeto e objetivos

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.

Instalando dependências e executando a aplicação

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.

Explorando as páginas e o layout inicial

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.

Examinando a pasta components e seus elementos

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.

Tipando componentes com ComponentProps e exemplificando o Textarea

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.

Estilizando o Textarea com 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);
}

Detalhando as pages e planejando comportamentos

O que há de diferente? Esta parte que chamamos de "pages", que são as páginas:

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.

Instalando o React DevTools e avançando para a navegação

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.

Explorando o React Router - Criando a primeira rota

Apresentando o problema e testando uma solução manual

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.

Adotando o react router e configurando o roteamento

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.

Configuração do BrowserRouter no projeto

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:

Tudo 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.

Declaração das rotas

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:

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>,
)
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:

Convenção de idioma nas URLs

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.

Testes e verificação

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!

Sobre o curso React: construa uma aplicação front-end completa

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:

Aprenda React acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas