Gerenciando rotas com React Router
Quando começamos a desenvolver um SPA, uma das primeiras coisas que precisamos definir é a forma como controlamos as rotas da aplicação. Em React isso não é diferente.
Quando começamos a desenvolver um SPA, uma das primeiras coisas que precisamos definir é a forma como controlamos as rotas da aplicação. Em React↳React37 conteúdos7 erros com React moderno que só aparecem em produção; e como evitarDev (Back & Front) · abr 2026React Native 0.76: o futuro do desenvolvimento mobileDev (Back & Front) · out 2024Simplificando componentes com React HooksDev (Back & Front) · mar 2019Ver tudo em Dev (Back & Front) → isso não é diferente. O React Router é uma lib completa para controle de rotas que permite que você consiga configurar as rotas utilizando o formato JSX e também disponibiliza uma API para você configurar diretamente via Javascript.
A lib trabalha com History API, mas também deixa a possibilidade de você trabalhar com Hash(#) se for necessário.
Ela possui features como: rotas aninhadas, lazy loading de componentes, matching para rotas dinâmicas e controle de transição de rotas, além de possuir suporte a server-rendering.
Para utilizá-la, basta instalar utilizando o npm:
npm install react-router --save
No exemplo abaixo, podemos ver como ficaria a estrutura básica para uma aplicação de agenda de contatos. Essa aplicação possuirá duas telas: uma para a listagem dos contatos e outra para a visualização detalhada do contato.
Teremos quatro componentes:
- App — O componente container da nossa aplicação;
- ContactList — Lista de contatos;
- ContactDetail — Componente de visualização de detalhes do contato;
- NotFound — Página 404.
import React from 'react';
import { render } from 'react-dom';
import { Router, Route, Link, browserHistory } from 'react-router';
const App = React.createClass({
render() {
const { children } = this.props;
return (
<div>
{/* you can insert the menu here */}
{children}
</div>
);
}
});
const contacts = [
{ id: 1, name: 'Jon Snow', email: 'winterishere@jonsnow.com'},
{ id: 2, name: 'Ygritte', email: 'youknownothing@jonsnow.com'},
];
const ContactList = React.createClass({
render() {
return (
<ul>
{contacts.map(contact => {
return(
<li>
<Link to={`/contacts/${contact.id}`}>
{contact.name} - {contact.email}
</Link>
</li>
);
})}
</ul>
);
}
});
const ContactDetail = React.createClass({
render() {
const { params } = this.props;
if(!params.id) return null;
return (
<div>
<h2>Contact Detail</h2>
<Link to='/contacts'>List all contacts</Link>
</div>
);
}
});
const NotFound = React.createClass({
render() {
return (<div>Page Not Found</div>);
}
});
render((
<Router history={browserHistory}>
<Route path='/' component={App}>
<Route path='contacts' component={ContactList}/>
<Route path='contacts/:id' component={ContactDetail} />
<Route path='*' component={NotFound}/>
</Route>
</Router>
), document.getElementById('root'));
No exemplo acima, os componentes estão no mesmo arquivo apenas para fins didáticos. É uma boa prática manter apenas uma definição de componente por arquivo.
No bloco abaixo, temos a definição de todas as nossas rotas. Os componentes que utilizamos para essa definição são o Router e o Route.
Router
Componente raiz da aplicação. Todas as rotas devem ser definidas dentro dele e deve existir somente um Router por aplicação.
O router espera receber o parâmetro history, que é o objeto que ele utilizará para o controle da transição das páginas. Esse objeto é diretamente importado do react-router, podendo ser o browserHistory ou o hashHistory.
Route
É cada rota da nossa aplicação. Espera como parâmetros as props:
- path — utiliza para fazer matching com a url;
- component — componente que será renderizado caso a url dê matching com o path.
O path aceita alguns formatos para definição da rota:
// Rota estática, ou fixa: path='contacts' // Rota com parâmetros: path='contacts/:id' // Rota com parâmetros opcionais: path='contacts(/:id)'
Os parâmetro passados pelas rotas chegam no componente através da propriedade params. No exemplo acima, poderíamos acessar o parâmetro idde dentro do componente respectivo à rota da seguinte forma:
componentDidMount() {
const id = this.props.params.id;
...
}
Outro formato aceito é utilizando o *, que funciona como um coringa:
path=’*’ fará matching com todas as rotas path='contacts/*' fará matching com todas as rotas a partir de contacts. ex: contacts/ contacts/example contacts/123
Mais detalhes sobre os formatos suportados podem ser encontrados nesse link da docs.
Um ponto importante a ressaltar é que somente uma rota fará matching por vez, e a prioridade delas vem de cima para baixo. Por esse motivo, conseguimos fazer nossa página 404 apenas utilizando o path=’*’ e colocando ele abaixo de todas as rotas. Caso não seja feito matching com nenhuma rota anterior, ele chega nessa rota e renderiza o component NotFound.
Rotas aninhadas
É comum em nossas aplicações utilizarmos rotas aninhadas. No nosso exemplo acima já estamos utilizando, mas talvez não tenha ficado evidente:
<Route path='/' component={App}>
<Route path='contacts' component={ContactList} />
...
</Route>
Nesse trecho, podemos observar que a rota contacts está aninhada a rota /que é nossa rota raiz.
Nossa rota raiz renderiza o componente App, que atualmente funciona apenas como um layout base da nossa aplicação.
Nele poderíamos colocar o rodapé, o menu e componentes que sempre estarão na tela, independentemente da rota em que estivermos.
Na imagem acima, na linha 7, acessamos a propriedade children, que é inserida pelo react router no nosso componente. Nesse caso, children seria o componente respectivo a uma rota aninhada. Por exemplo:
// URL atual: 'http://app.myapp.com/contacts'
<Route path='/' component={App}>
<Route path='contacts' component={ContactList} />
<Route path='contacts/:id' component={ContactDetail} />
</Route>
Dada a URL atual e a nossa configuração de rotas, o children do nosso componente App seria o componente ContactList.
Abaixo segue um layout que com frequência vemos em aplicações:
No layout acima, temos o menu superior e a sidebar que estarão em todas as telas e temos o conteúdo central, que mudará de uma rota para outra.
Nesse caso, poderíamos manter o Menu e a Sidebar no nosso componente App, renderizando o children ao centro.
render () {
return (
<div>
<Menu />
<Sidebar />
<section className='content-wrapper'>
{children}
</section>
</div>
);
}
Em nosso exemplo da agenda, só utilizamos um nível de aninhamento de rota, mas é possível utilizar quantos forem necessários:
<Route path='/' component={App}>
<Route path='contacts' component={ContactList} />
<Route path='contacts:id' component={ContactDetail}>
<Route path='calls' component={ContactCalls} />
</Route>
</Route>
Nesse exemplo acima, temos uma rota aninhada dentro da visualização do contato. Nessa rota iríamos mostrar, abaixo das informações do contato, uma lista de ligações feitas para o mesmo.
Quando a rota calls fizer matching, o componente ContactCalls estará disponível através da propriedade children do componente ContactDetail.
O ContactCall fica como o children de ContactDetail que por sua vez é children de App.
Link
O componente Link é utilizado para fazer a navegação das páginas. esse componente aceita os seguintes parâmetros:
to
O destino para o link, que pode ser passado em dois formatos, string ou objeto.
Em caso de string, deve ser o caminho absoluto para a página, exemplo:
<Link to='/contacts/123'>Contato 123</Link>
Em caso de objeto, pode conter os seguintes parâmetros:
{
pathname: 'String representando o caminho para o link',
query: 'Um objeto com chave valor dos parâmetros da url',
hash: 'Uma hash para colocar na URL, ex: #uma-hash.',
state: 'state a ser persistido para o location'
}
- activeClassName: className a ser inserido no link quando a url do link em questão estiver ativa. É uma forma fácil de estilizar seu link ativo no menu de navegação.
- activeStyle: Bem parecido com o activeClassName, mas ao invés do className, aceita um objeto de estilos CSS.
Os demais atributos podem ser encontrado nesse link da docs.
Com esses componentes, já é possível construir uma aplicação baseada em rotas. Mas o controle de rotas não para apenas por aqui, há outras questões como rotas dinâmicas e controle de autenticação de usuário que eu pretendo abordar em artigos futuros.
Para se aprofundar no tema, aconselho começar pela documentação que hoje se encontra no Github.












John Calistro
Cesar Gimenes
José Carlos Macoratti





