Se você estiver direcionando para ambientes de navegador, precisará usar o react-router-dom
pacote, em vez de react-router
. Eles estão seguindo a mesma abordagem que Reagir fez, a fim de separar o núcleo, ( react
) eo código de plataforma específica, ( react-dom
, react-native
), com a sutil diferença que você não precisa instalar dois pacotes separados, de modo que os pacotes ambiente contêm tudo você precisa. Você pode adicioná-lo ao seu projeto como:
yarn add react-router-dom
ou
npm i react-router-dom
A primeira coisa que você precisa fazer é fornecer <BrowserRouter>
o componente principal como principal no aplicativo. <BrowserRouter>
usa a history
API HTML5 e a gerencia para você, para que você não precise se preocupar em instanciar você mesmo e transmiti-lo ao <BrowserRouter>
componente como um suporte (como era necessário nas versões anteriores).
Na V4, para navegar programaticamente, é necessário acessar o history
objeto, disponível através do React context
, desde que você tenha um componente de <BrowserRouter>
provedor como o principal pai no aplicativo. A biblioteca expõe através do contexto o router
objeto que ele próprio contém history
como uma propriedade. A history
interface oferece vários métodos de navegação, como push
, replace
e goBack
, entre outros. Você pode verificar a lista completa de propriedades e métodos aqui .
Nota importante para usuários Redux / Mobx
Se você estiver usando redux ou mobx como sua biblioteca de gerenciamento de estado em seu aplicativo, poderá ter problemas com componentes que devem reconhecer o local, mas não são renderizados novamente depois de acionar uma atualização de URL
Isso está acontecendo porque react-router
passa location
para os componentes usando o modelo de contexto.
Tanto o connect quanto o observador criam componentes cujos métodos shouldComponentUpdate fazem uma comparação superficial dos adereços atuais e dos adereços seguintes. Esses componentes serão renderizados novamente somente quando pelo menos um suporte for alterado. Isso significa que, para garantir que eles sejam atualizados quando o local mudar, eles precisarão de um suporte que mude quando o local mudar.
As 2 abordagens para resolver isso são:
- Enrole o componente conectado em um caminho sem caminho
<Route />
. O location
objeto atual é um dos adereços que a <Route>
passa para o componente que ele renderiza
- Enrole o componente conectado com o
withRouter
componente de ordem superior, que de fato tem o mesmo efeito e injeta location
como suporte
Deixando isso de lado, há quatro maneiras de navegar programaticamente, ordenadas por recomendação:
1.- Usando um <Route>
componente
Promove um estilo declarativo. Antes da v4, os
<Route />
componentes eram colocados no topo da hierarquia de componentes, tendo que pensar na estrutura de suas rotas com antecedência. No entanto, agora você pode ter
<Route>
componentes em
qualquer lugar da sua árvore, permitindo um controle mais preciso da renderização condicional, dependendo da URL.
Route
injeta
match
,
location
e
history
como adereços em seu componente. Os métodos de navegação (tais como
push
,
replace
,
goBack
...) estão disponíveis como as propriedades do
history
objecto.
Existem três maneiras de renderizar algo com a Route
, usando ad component
, render
ou children
adereços, mas não use mais de um no mesmo Route
. A escolha depende do caso de uso, mas basicamente as duas primeiras opções renderizarão seu componente apenas se path
corresponder ao local da URL, enquanto que children
o componente será renderizado se o caminho corresponder ao local ou não (útil para ajustar a interface do usuário com base no URL Coincidindo).
Se você quiser personalizar a sua saída de renderização de componente , você precisa envolver sua componente em uma função e usar a render
opção, a fim de passar para o seu componente quaisquer outros adereços que você deseja, para além de match
, location
e history
. Um exemplo para ilustrar:
import { BrowserRouter as Router } from 'react-router-dom'
const ButtonToNavigate = ({ title, history }) => (
<button
type="button"
onClick={() => history.push('/my-new-location')}
>
{title}
</button>
);
const SomeComponent = () => (
<Route path="/" render={(props) => <ButtonToNavigate {...props} title="Navigate elsewhere" />} />
)
const App = () => (
<Router>
<SomeComponent /> // Notice how in v4 we can have any other component interleaved
<AnotherComponent />
</Router>
);
2.- Usando withRouter
HoC
Esse componente de ordem superior injeta os mesmos adereços que Route
. No entanto, ele carrega a limitação de que você pode ter apenas 1 HoC por arquivo.
import { withRouter } from 'react-router-dom'
const ButtonToNavigate = ({ history }) => (
<button
type="button"
onClick={() => history.push('/my-new-location')}
>
Navigate
</button>
);
ButtonToNavigate.propTypes = {
history: React.PropTypes.shape({
push: React.PropTypes.func.isRequired,
}),
};
export default withRouter(ButtonToNavigate);
3.- Usando um Redirect
componente
A renderização de um
<Redirect>
navegará para um novo local. Mas lembre-se de que,
por padrão , o local atual é substituído pelo novo, como redirecionamentos do lado do servidor (HTTP 3xx). O novo local é fornecido pelo
to
prop, que pode ser uma sequência (URL para a qual redirecionar) ou um
location
objeto. Se você deseja
inserir uma nova entrada no histórico , passe também um
push
suporte e defina-o como
true
<Redirect to="/your-new-location" push />
4.- Acessando router
manualmente através do contexto
Um pouco desencorajado porque o
contexto ainda é uma API experimental e é provável que quebre / mude em versões futuras do React
const ButtonToNavigate = (props, context) => (
<button
type="button"
onClick={() => context.router.history.push('/my-new-location')}
>
Navigate to a new location
</button>
);
ButtonToNavigate.contextTypes = {
router: React.PropTypes.shape({
history: React.PropTypes.object.isRequired,
}),
};
Escusado será dizer que também existem outros componentes do roteador destinados a ecossistemas que não são navegadores, como o <NativeRouter>
que replica uma pilha de navegação na memória e tem como alvo a plataforma React Native, disponível através do react-router-native
pacote.
Para qualquer referência adicional, não hesite em dar uma olhada nos documentos oficiais . Há também um vídeo feito por um dos co-autores da biblioteca que fornece uma introdução bastante interessante ao reag-router v4, destacando algumas das principais mudanças.