React Router DOM: como funciona o roteamento em aplicações React

Rocketseat

Conheça o Rocketseat Para Empresas
Oferecemos soluções personalizadas para empresas de todos os portes.
Imagine que você está construindo uma cidade digital. Cada prédio, praça ou loja é um componente React. Como os habitantes (usuários) se movem de um lugar para outro? Eles precisam de ruas e endereços. Em uma aplicação web, essas ruas são as URLs, e o sistema que gerencia essas rotas é o React Router DOM.
Se você está começando em React e a ideia de roteamento React parece um mapa complexo, pode relaxar. Estamos aqui para te guiar, passo a passo. Acredite, é totalmente possível começar e dominar a navegação SPA em suas aplicações. Este material foi feito para quem já deu os primeiros passos com componentes e estado, e agora quer construir aplicações mais completas e dinâmicas.
O que é o React Router DOM e por que usar?
O React Router DOM é a biblioteca padrão da comunidade para lidar com roteamento em aplicações React. De forma simples, ela permite que sua aplicação tenha múltiplas "páginas" ou "telas", mesmo sendo tecnicamente uma única página. É a ferramenta que sincroniza a interface da sua aplicação com a URL no navegador, permitindo uma navegação fluida sem a necessidade de recarregar a página inteira a cada clique.
Pense em como você navega no Instagram ou no Facebook. Ao clicar em um perfil ou em uma foto, o conteúdo da página muda instantaneamente, a URL é atualizada, mas o navegador não faz aquele "piscar" de recarregamento total. Isso é o roteamento do lado do cliente (client-side routing) em ação, uma das principais características de uma Single-Page Application (SPA).
Aplicações de página única vs. aplicações com múltiplas rotas
Para entender o valor do React Router, é importante diferenciar dois modelos de arquitetura web. Uma aplicação tradicional, conhecida como Multi-Page Application (MPA), funciona como a web funcionava em seus primórdios. Cada vez que você clica em um link, o navegador envia uma requisição ao servidor, que por sua vez devolve um arquivo HTML completamente novo. Esse processo causa um recarregamento total da página.
Já uma Single-Page Application (SPA), o modelo que o React popularizou, carrega um único arquivo HTML inicial. A partir daí, toda a navegação e alteração de conteúdo são gerenciadas por JavaScript diretamente no navegador do usuário. O React Router é a biblioteca que possibilita que uma SPA simule múltiplas páginas, alterando o que é exibido na tela com base na URL, mas sem novos recarregos.
A escolha entre esses dois modelos arquitetônicos impacta diretamente a estratégia do produto. Uma SPA, com sua experiência de usuário fluida e rápida, é ideal para aplicações onde a retenção e o engajamento são cruciais, como dashboards, ferramentas SaaS e redes sociais. Por outro lado, o modelo MPA, por ter cada página como um documento separado, tende a ser mais facilmente indexado por buscadores, sendo uma escolha forte para negócios que dependem de tráfego orgânico para aquisição de clientes, como blogs e grandes sites de e-commerce. Portanto, ao aprender a construir SPAs com roteamento, a pessoa desenvolvedora está adquirindo uma habilidade que influencia diretamente o posicionamento de um produto no mercado.
A tabela a seguir resume as principais diferenças:
Característica | SPA | MPA |
Experiência do usuário | Fluida e rápida, sem recarregamentos a cada clique. | Interrupções visíveis a cada navegação com recarregamento da página. |
Performance | Carga inicial pode ser maior, mas a navegação entre páginas é quase instantânea. | Carga inicial de cada página é independente e geralmente mais rápida, mas a navegação é mais lenta. |
SEO | Requer técnicas específicas para garantir a indexação correta do conteúdo. | Amigável por padrão, pois cada página é um HTML distinto e facilmente rastreável. |
Complexidade de desenvolvimento | Geralmente promove um desacoplamento claro entre front-end e back-end. | A lógica de front-end e back-end pode ser mais interligada. |
Casos de uso ideais | Dashboards, redes sociais, aplicações SaaS, onde a experiência interativa é prioridade. | Blogs, sites de notícias, e-commerce com vasto catálogo de produtos. |
Vantagens do roteamento client-side
Adotar o roteamento client-side com o React Router DOM traz benefícios concretos para suas aplicações single-page:
- Performance e UX fluida: como não há recarregamento completo da página, as transições entre diferentes seções da aplicação são muito mais rápidas e suaves, proporcionando uma experiência de usuário similar à de um aplicativo nativo de desktop ou mobile.
- URLs compartilháveis: cada visualização da sua aplicação pode ter uma URL única. Isso significa que a pessoa usuária pode favoritar uma página específica ou compartilhar um link direto para um conteúdo, algo que seria complexo em uma SPA sem um sistema de roteamento.
- Navegação consistente: ele se integra perfeitamente com os botões de "voltar" e "avançar" do navegador, mantendo o comportamento esperado pelo usuário e melhorando a usabilidade.
- A URL como fonte de estado: a URL se torna uma parte confiável do estado da sua aplicação. Você pode usar a informação contida nela para decidir o que renderizar, qual dado buscar e como a interface deve se comportar.
É válido notar que essa performance aprimorada na navegação vem com uma contrapartida. A carga inicial de uma SPA pode ser um pouco mais demorada, pois o navegador precisa baixar não apenas o código da página inicial, mas também o JavaScript necessário para gerenciar todas as outras rotas possíveis. Para contornar isso em aplicações maiores, profissionais de tecnologia utilizam técnicas como code-splitting (divisão de código), que permite carregar o código de cada rota apenas quando ele é necessário.
Primeiros passos com React Router DOM
Vamos colocar a mão na massa. Esta seção é um guia prático para você instalar e configurar o roteamento em um novo projeto React.
Instalação e configuração inicial
Para começar a usar o React Router DOM, o primeiro passo é instalá-lo em seu projeto. Abra o terminal na pasta raiz do seu projeto React e execute o seguinte comando:
npm install react-router-dom
react-router-dom como uma dependência no seu arquivo package.json. Após a instalação, você verá uma entrada similar a esta na seção de dependências do seu arquivo:
"dependencies": { "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.23.1", // exemplo de versão ... ... ... },
Com a biblioteca instalada, já podemos começar a configurar nossa estrutura.
Estrutura básica de um projeto com roteamento
Manter um projeto organizado é um passo importante para a manutenibilidade. Uma convenção comum em projetos React é separar os componentes que representam páginas inteiras dos componentes de UI reutilizáveis.
Para iniciantes, sugerimos a seguinte estrutura de pastas:
/src |-- /components // Componentes de UI reutilizáveis (Button, Input, Card, etc.) |-- /pages // Componentes que representam uma página (Home, Sobre, Contato) |-- App.js // Onde a configuração das rotas vai morar |-- index.js // Ponto de entrada da aplicação
O próximo passo é "habilitar" o roteamento em toda a aplicação. Isso é feito envolvendo nosso componente principal, o
App, com um componente do React Router chamado BrowserRouter. Essa estrutura é um exemplo prático de um padrão de projeto muito poderoso em React, o Provider Pattern.Ao envolver a aplicação com
<BrowserRouter>, você está criando um "contexto de roteamento". Esse contexto disponibiliza todas as funcionalidades de navegação para qualquer componente dentro da árvore, sem a necessidade de passar props manualmente. É por isso que hooks como useNavigate e useParams, que veremos mais adiante, funcionam de forma tão integrada em qualquer parte do seu app.Componentes principais do React Router DOM
O React Router DOM opera com base em alguns componentes principais. Entender o papel de cada um é o que vai te dar a confiança para construir qualquer fluxo de navegação.
BrowserRouter como provedor de contexto
O
BrowserRouter é o componente que ativa o roteamento na sua aplicação. Ele deve envolver o componente raiz do seu app, geralmente no arquivo src/index.js ou src/main.jsx. Ele utiliza a API de Histórico nativa do navegador para manter a sua interface sincronizada com a URL, sendo o verdadeiro "cérebro" da operação.Veja como fica a configuração no ponto de entrada da aplicação:
import React from 'react'; import ReactDOM from 'react-dom/client'; import { BrowserRouter } from 'react-router-dom'; import App from './App'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <BrowserRouter> <App /> </BrowserRouter> </React.StrictMode> );
Embora o
BrowserRouter seja o mais comum para aplicações web, existem outros tipos de roteadores para cenários específicos, como o MemoryRouter para ambientes que não possuem uma barra de endereço, como em testes ou em aplicações React Native.Routes e Route, definindo as rotas
Uma vez que o
BrowserRouter está configurado, você precisa definir quais "páginas" sua aplicação terá. Isso é feito com os componentes Routes e Route.<Routes>: sua função é analisar todas as suas rotas filhas (<Route>) e renderizar aquela que melhor corresponde à URL atual do navegador.
<Route>: cada componente<Route>é uma declaração de mapeamento. Ele conecta umpath(o caminho na URL, como/sobre) a umelement(o componente React que deve ser exibido nesse caminho).
Aqui está um exemplo prático de como definir algumas rotas dentro do seu componente
App:import { Routes, Route } from 'react-router-dom'; import Home from './pages/Home'; import Profile from './pages/Profile'; import Settings from './pages/Settings'; // Criando componentes const Mayk = () => <div>Página inicial do Mayk</div>; const Diego = () => <div>Página de perfil do Diego</div>; const Rodrigo = () => <div>Página de configurações do Rodrigo</div>; function App() { return ( <div> <Routes> <Route path="/" element={<Mayk />} /> <Route path="/diego" element={<Diego />} /> <Route path="/rodrigo" element={<Rodrigo />} /> </Routes> </div> ); }
Navegação entre páginas com Link e NavLink
Com as rotas definidas, como o usuário navega entre elas? Se você usar a tag
<a> do HTML tradicional, você quebrará a experiência de uma SPA. Uma tag <a> com href sempre acionará um recarregamento completo da página, perdendo todo o estado da sua aplicação React e causando um "piscar" na tela.A solução do React Router é o componente
<Link>. Ele renderiza uma tag <a> no HTML final, mas intercepta o evento de clique. Em vez de deixar o navegador fazer o recarregamento, o <Link> atualiza a URL programaticamente e informa ao React Router para renderizar o novo componente correspondente. Essa troca de responsabilidade é o que define o "contrato" de uma SPA: a aplicação, e não o navegador, assume o controle da navegação.<Link>: para criar links de navegação básicos.
<NavLink>: variação especial do<Link>que "sabe" quando a rota para a qual ele aponta está ativa. Isso é extremamente útil para estilizar o link da página atual em um menu de navegação, por exemplo, destacando-o.
Veja a diferença na prática:
import { Link, NavLink } from 'react-router-dom'; function Navigation() { return ( <nav> {/* Link simples para a página inicial */} <Link to="/">Home</Link> {/* NavLink para a página "Sobre", com estilo condicional */} <NavLink to="/sobre" style={({ isActive }) => { return { fontWeight: isActive ? 'bold' : 'normal', color: isActive? "#8257E5" : "black", }; }} > Sobre </NavLink> </nav> ); }
Configurando o projeto do zero
Crie um novo projeto React com o Vite (a ferramenta recomendada atualmente) ou Create React App:
npm create vite@latest meu-app-roteado -- --template react cd meu-app-roteado
Instale o React Router DOM:
npm install react-router-dom
Crie a estrutura de pastas que sugerimos anteriormente, com uma pasta
pages dentro de src.Implementando páginas básicas
Dentro de
src/pages, crie três arquivos: Home.jsx, Sobre.jsx e Contato.jsx.src/pages/Home.jsx:const Home = () => { return <h1>Página Inicial</h1>; }; export default Home;
src/pages/Sobre.jsx:const Sobre = () => { // Usando nomes fictícios da comunidade Rocketseat, como pedido no plano const equipe = [ { id: 1, nome: "Laís" }, { id: 2, nome: "Isabela" }, { id: 3, nome: "Fernanda" }, ]; return ( <div> <h1>Sobre Nós</h1> <p>Nossa equipe é formada por: {equipe.map(m => m.nome).join(', ')}.</p> </div> ); }; export default Sobre;
src/pages/Contato.jsx:const Contato = () => { return <h1>Página de Contato</h1>; }; export default Contato;
Agora, vamos configurar o arquivo principal
src/App.jsx para usar essas páginas e criar a navegação.src/App.jsx:import { Routes, Route, Link } from 'react-router-dom'; import Home from './pages/Home'; import Sobre from './pages/Sobre'; import Contato from './pages/Contato'; import './App.css'; // Estilização básica function App() { return ( <div className="App"> <header> <nav> <Link to="/">Home</Link> <Link to="/sobre">Sobre</Link> <Link to="/contato">Contato</Link> </nav> </header> <main> <Routes> <Route path="/" element={<Home />} /> <Route path="/sobre" element={<Sobre />} /> <Route path="/contato" element={<Contato />} /> </Routes> </main> </div> ); } export default App;
Não se esqueça de envolver o
<App /> com <BrowserRouter> no seu arquivo src/main.jsx.src/main.jsx:import React from 'react'; import ReactDOM from 'react-dom/client'; import { BrowserRouter } from 'react-router-dom'; import App from './App'; import './index.css'; ReactDOM.createRoot(document.getElementById('root')).render( <React.StrictMode> <BrowserRouter> <App /> </BrowserRouter> </React.StrictMode> );
Testando a navegação
Execute sua aplicação com
npm run dev (para Vite) ou npm start (para Create React App). Você verá sua aplicação com os três links de navegação. Clique neles e observe:- A URL na barra de endereços do navegador muda.
- O conteúdo da página (o
<h1>) muda para corresponder à página clicada.
- A página inteira não recarrega.
Parabéns, você acabou de criar sua primeira aplicação React com roteamento!
Conceitos para expandir conhecimento
Com a base sólida, podemos explorar alguns padrões mais avançados que são comuns em aplicações do mundo real.
Parâmetros de rota e dados dinâmicos
Muitas vezes, você precisará de rotas que não são fixas, mas dinâmicas. Por exemplo, a página de perfil de um usuário (
/perfil/diego), a página de um produto (/produtos/cadeira-gamer) ou de um post de blog (/blog/guia-de-react). Seria inviável criar uma rota para cada usuário ou produto.É aqui que entram os parâmetros de rota. Você pode definir um "segmento dinâmico" na sua rota usando dois pontos (
:). Para acessar o valor desse parâmetro dentro do seu componente, você usa o hook useParams.Este conceito marca um salto importante na sua jornada: a URL deixa de ser apenas um endereço e se torna parte do estado da sua aplicação. O parâmetro extraído da URL, como um ID, é frequentemente usado para buscar dados específicos de uma API. Assim, a URL passa a ditar diretamente o conteúdo exibido, permitindo que um único componente sirva para criar um número infinito de páginas únicas.
Exemplo:
Defina a rota dinâmica em
App.jsx:<Route path="/perfil/:userId" element={<UserProfile />} />
Crie o componente
UserProfile.jsx e use o hook useParams:// src/pages/UserProfile.jsx import { useParams } from 'react-router-dom'; function UserProfile() { // O hook useParams retorna um objeto com os parâmetros da URL. // A chave do objeto é o nome que demos ao parâmetro na rota (:userId). let { userId } = useParams(); return ( <div> <h2>Perfil do usuário:</h2> <p>Exibindo informações: <strong>{userId}</strong>.</p> </div> ); } export default UserProfile;
Agora, se você navegar para
/perfil/mayk, o componente renderizará "Exibindo informações para o usuário: mayk". Se for para /perfil/rodrigo, o nome mudará de acordo.Rotas aninhadas e layouts
Aplicações complexas frequentemente possuem layouts compartilhados. Imagine um painel de controle (dashboard) com uma barra lateral e um cabeçalho que permanecem os mesmos enquanto o conteúdo principal muda. As rotas aninhadas são a solução perfeita para isso.
O padrão consiste em criar uma rota "pai" que renderiza o layout compartilhado. Dentro desse componente de layout, você usa o componente
<Outlet />. Ele funciona como um marcador de posição, indicando onde os componentes das rotas "filhas" devem ser renderizados.Essa abordagem é uma aplicação poderosa do princípio de composição e da filosofia "Don't Repeat Yourself" (DRY) na arquitetura de UI. O layout compartilhado é definido uma única vez, e o
<Outlet /> desacopla essa estrutura do conteúdo dinâmico. Para alterar o cabeçalho de todas as páginas do dashboard, você edita apenas um arquivo, tornando a aplicação muito mais fácil de manter e escalar.Exemplo:
Crie um componente de layout:
// src/layouts/DashboardLayout.jsx import { Outlet, Link } from 'react-router-dom'; const DashboardLayout = () => ( <div> <header> <h1>Meu Dashboard</h1> </header> <aside> <nav> <Link to="/dashboard">Início</Link> | <Link to="/dashboard/stats">Estatísticas</Link> </nav> </aside> <main> {/* O conteúdo das rotas aninhadas será renderizado aqui */} <Outlet /> </main> </div> ); export default DashboardLayout;
Configure as rotas aninhadas em
App.jsx:import DashboardLayout from './layouts/DashboardLayout'; import DashboardHome from './pages/DashboardHome'; import DashboardStats from './pages/DashboardStats'; <Routes> {/*... outras rotas... */} <Route path="/dashboard" element={<DashboardLayout />}> <Route index element={<DashboardHome />} /> {/* Rota padrão para /dashboard */} <Route path="stats" element={<DashboardStats />} /> {/* Rota para /dashboard/stats */} </Route> </Routes>
Tratamento de rotas não encontradas (404)
Conheça o Rocketseat Para Empresas
Oferecemos soluções personalizadas para empresas de todos os portes.
Artigos_
Explore conteúdos relacionados
Descubra mais artigos que complementam seu aprendizado e expandem seu conhecimento.
NewsletterReceba conteúdos inéditos e novidades gratuitamente
