Com react-router
eu posso usar o Link
elemento para criar links que são nativamente tratados pelo roteador de reação.
Eu vejo internamente que chama this.context.transitionTo(...)
.
Eu quero fazer uma navegação. Não de um link, mas de uma seleção suspensa (como exemplo). Como posso fazer isso no código? O que é this.context
?
Eu vi o Navigation
mixin, mas posso fazer isso sem mixins
?
reactjs
react-router
George Mauer
fonte
fonte
Respostas:
Há um novo
useHistory
gancho no React Router> 5.1.0 se você estiver usando o React> 16.8.0 e componentes funcionais.Com a v4 do React Router, há três abordagens que você pode adotar para o roteamento programático dentro dos componentes.
withRouter
componente de ordem superior.<Route>
context
.O React Router é principalmente um invólucro em torno da
history
biblioteca.history
lida com a interação com o navegadorwindow.history
para você com seu histórico de hash e navegador. Ele também fornece um histórico de memória que é útil para ambientes que não possuem um histórico global. Isso é particularmente útil no desenvolvimento de aplicativos móveis (react-native
) e no teste de unidade com o Node.Uma
history
instância possui dois métodos para navegar:push
ereplace
. Se você considerar o localhistory
como uma matriz de locais visitados,push
adicionará uma nova localização à matriz ereplace
substituirá a localização atual na matriz pela nova. Normalmente, você desejará usar opush
método quando estiver navegando.Em versões anteriores do Reagir Router, você tinha que criar o seu próprio
history
exemplo, mas em v4 o<BrowserRouter>
,<HashRouter>
e<MemoryRouter>
componentes irão criar um navegador, haxixe e instâncias de memória para você. O React Router disponibiliza as propriedades e os métodos dahistory
instância associada ao seu roteador por meio do contexto, sob orouter
objeto1. Use o
withRouter
componente de ordem superiorO
withRouter
componente de ordem superior injeta ohistory
objeto como um suporte do componente. Isso permite que você acesse os métodospush
ereplace
sem precisar lidar com oscontext
.2. Use composição e renderize um
<Route>
O
<Route>
componente não é apenas para locais correspondentes. Você pode renderizar uma rota sem caminho e ela sempre corresponderá à localização atual . O<Route>
componente passa os mesmos adereços quewithRouter
, portanto, você poderá acessar oshistory
métodos através dohistory
adereço.3. Use o contexto *
Mas você provavelmente não deveria
A última opção é aquela que você deve usar apenas se sentir-se à vontade para trabalhar com o modelo de contexto do React (a API de contexto do React é estável a partir da v16).
1 e 2 são as escolhas mais simples de implementar; portanto, na maioria dos casos de uso, são as suas melhores apostas.
fonte
withRouter
vez de passarhistory
por todos os meus componentes? GAHH I necessidade de gastar mais docs leitura vez ...history.push('/new-location')
sem anexar esse comportamento a um Button ou outro elemento DOM?Unexpected use of 'history' no-restricted-globals
context
não é mais experimental a partir da reação 16.Você pode usar o novo
useHistory
gancho em Componentes Funcionais e navegar programaticamente:No 4.0 e acima, use o histórico como suporte do seu componente.
NOTA: this.props.history não existe no caso em que seu componente não foi renderizado
<Route>
. Você deve usar o<Route path="..." component={YourComponent}/>
this.props.history em YourComponentNo 3.0 e acima, use o roteador como suporte do seu componente.
Na 2.4 e acima, use um componente de ordem superior para obter o roteador como suporte do seu componente.
Esta versão é compatível com a versão 1.x, portanto não há necessidade de um Guia de atualização. Apenas passar pelos exemplos deve ser bom o suficiente.
Dito isso, se você deseja mudar para o novo padrão, há um módulo browserHistory dentro do roteador que você pode acessar com
import { browserHistory } from 'react-router'
Agora você tem acesso ao histórico do navegador, para poder executar ações como empurrar, substituir, etc ...
browserHistory.push('/some/path')
Leitura adicional: Histórias e navegação
Não entrarei em detalhes de atualização. Você pode ler sobre isso no Guia de atualização
A principal mudança sobre a questão aqui é a mudança do Navigation mixin para o History. Agora, ele está usando a API do histórico do navegador para alterar a rota, e usaremos a
pushState()
partir de agora.Aqui está um exemplo usando o Mixin:
Observe que isso
History
vem do projeto rackt / history . Não do próprio React-Router.Se você não quiser usar o Mixin por algum motivo (talvez por causa da classe ES6), poderá acessar o histórico que obtém do roteador
this.props.history
. Ele estará acessível apenas para os componentes renderizados pelo seu roteador. Portanto, se você quiser usá-lo em qualquer componente filho, ele precisará ser transmitido como um atributo viaprops
.Você pode ler mais sobre a nova versão na documentação 1.0.x
Aqui está uma página de ajuda especificamente sobre como navegar fora do seu componente
Ele recomenda pegar uma referência
history = createHistory()
e solicitarreplaceState
isso.Eu entrei no mesmo problema e só consegui encontrar a solução com o Navegador mixin que acompanha o reat-router.
Aqui está como eu fiz isso
Consegui ligar
transitionTo()
sem a necessidade de acessar.context
Ou você pode experimentar o sofisticado ES6
class
O React-Router-Redux possui alguns métodos disponíveis que permitem uma navegação simples a partir de criadores de ação interna. Isso pode ser particularmente útil para pessoas que possuem arquitetura existente no React Native e desejam utilizar os mesmos padrões no React Web com o mínimo de sobrecarga.
Explore os seguintes métodos:
push(location)
replace(location)
go(number)
goBack()
goForward()
Aqui está um exemplo de uso, com Redux-Thunk :
./actioncreators.js
./viewcomponent.js
fonte
v2.4.0
mas a abordagem mencionada não funciona para mim, meu aplicativo não é processado e o console sai:Uncaught TypeError: (0 , _reactRouter.withRouter) is not a function
aqui está o link para minha postagem do SO: stackoverflow.com/questions/37306166/…2.6.0
.3.0.x
? Muitas pessoas parecem usar ocontext
caminho.this.props.history
não existe no caso em que seu componente não foi renderizado<Route>
. Você deve usar<Route path="..." component={YourComponent}/>
para terthis.props.history
emYourComponent
.Para a versão mais recente (
v2.0.0-rc5
), o método de navegação recomendado é empurrar diretamente para o singleton do histórico. Você pode ver isso em ação no documento Navegando fora dos componentes .Trecho relevante:
Se você estiver usando a API do roteador de reação mais recente, precisará usar o
history
from fromthis.props
dentro dos componentes para:Ele também oferece,
pushState
mas é preterido por avisos registrados.Se estiver usando
react-router-redux
, ele oferece umapush
função que você pode despachar da seguinte forma:No entanto, isso pode ser usado apenas para alterar o URL, não para realmente navegar para a página.
fonte
import { browserHistory } from './react-router'
mas cria um histórico usandoimport createBrowserHistory from 'history/lib/createBrowserHistory'
. Mais tarde, você pode acessarhistory
a partir dos componentes adereços:this.props.history('/some/path')
var browserHistory = require('react-router').browserHistory; browserHistory.goBack();
push
apenas altera o URL, na verdade não altera a página. Para fazer as duas coisas, a importaçãobrowserHistory
dereact-router
e usobrowserHistory.push('/my-cool-path')
. Infelizmente, isso não é super fácil de encontrar. github.com/reactjs/react-router/blob/master/docs/guides/…react-router
v4Veja como você faz isso
react-router v2.0.0
com o ES6 .react-router
se afastou dos mixins.fonte
history
singleton conforme declarado pelo @Bobby. Você poderia usarcontext.router
, mas você está fazendo isso muito difícil de teste de unidade esses componentes como instanciar apenas esse componente não terá isso no contexto.No final, gosto de ter um único objeto histórico que possa transportar até componentes externos. O que eu gosto de fazer é ter um único arquivo history.js que importo sob demanda e apenas o manipulo.
Você apenas precisa mudar
BrowserRouter
para o roteador e especificar o suporte de histórico. Isso não muda nada para você, exceto que você tem seu próprio objeto de histórico que você pode manipular como quiser.Você precisa instalar o histórico , a biblioteca usada por
react-router
.Exemplo de uso, notação ES6:
history.js
BasicComponent.js
Se você precisar navegar de um componente que é realmente renderizado a partir de um
Route
componente, também poderá acessar o histórico a partir de adereços, assim:BasicComponent.js
fonte
Router
vez deBrowserRouter
.BrowserRouter
cria e mantém ohistory
objeto para você. Você não deve usar como padrão para a criação de seu próprio país, só se você [ "necessidade profunda integração com ferramentas de gerenciamento de estado como Redux".] Reacttraining.com/react-router/web/api/Routerthis.props.history
, ainda não encontrei uma solução que possa me ajudar a fazer algo em uma classe que não seja um componente ou qualquer outra ferramenta que não seja construída como um componente React ao qual você pode passar adereços. Obrigado pelo seu feedback :)Para este, que não controla o lado do servidor e, por isso, está usando o roteador hash v2:
Coloque seu histórico em um arquivo separado (por exemplo, app_history.js ES6):
E use-o em qualquer lugar!
Seu ponto de entrada para o react-router (app.js ES6):
Sua navegação dentro de qualquer componente (ES6):
fonte
history
de qualquer abordagem agoratl: dr;
A resposta simples e declarativa é que você precisa usar
<Redirect to={URL} push={boolean} />
em combinação comsetState()
Exemplo completo aqui . Leia mais aqui .
PS. O exemplo usa inicializadores de propriedades do ES7 + para inicializar o estado. Olhe aqui também, se você estiver interessado.
fonte
withRouter
não funcionou quando já estava na rota que está sendo recarregada. No nosso caso, tivemos que fazer seletivamentesetState
(causarreturn <Redirect>
) se já estiver na rota ouhistory.push()
de outro lugar.Você pode fazer isso sem mixins também.
O problema com os contextos é que ele não está acessível, a menos que você defina o
contextTypes
na classe.Quanto ao contexto, é um objeto, como adereços, que é transmitido de pai para filho, mas é transmitido implicitamente, sem precisar redefinir adereços a cada vez. Consulte https://www.tildedave.com/2014/11/15/introduction-to-contexts-in-react-js.html
fonte
Eu tentei pelo menos 10 maneiras de fazer isso antes que algo desse certo!
A
withRouter
resposta de @Felipe Skinner foi um pouco esmagadora para mim, e eu não tinha certeza se queria criar novos nomes de classe "ExportedWithRouter".Aqui está a maneira mais simples e limpa de fazer isso, por volta do atual React-Router 3.0.0 e ES6:
ou, se não for sua classe padrão, exporte como:
Observe que no 3.xx, o
<Link>
próprio componente está sendo usadorouter.push
, para que você possa passar o que quer que você passe na<Link to=
tag, como:fonte
200 OK
vez de30x
código. Como posso corrigir esse problema?Para fazer a navegação programaticamente, você precisa enviar um novo histórico para os props.history no seu
component
, para que algo assim possa fazer o trabalho por você:fonte
Para os componentes do ES6 + React, a seguinte solução funcionou para mim.
Eu segui o skinner Felippe, mas adicionei uma solução completa para ajudar iniciantes como eu.
Abaixo estão as versões que eu usei:
Abaixo está meu componente react, onde usei a navegação programática usando o react-router:
Abaixo está a configuração do meu roteador:
fonte
Pode não ser a melhor abordagem, mas ... Usando o react-router v4, o seguinte TypeScript pode dar uma idéia para alguns.
No componente renderizado abaixo, por exemplo
LoginPage
, orouter
objeto está acessível e apenas chamarouter.transitionTo('/homepage')
para navegar.O código de navegação foi retirado de .
"react-router": "^4.0.0-2",
"react": "^15.3.1",
fonte
Você pode usar
withRouter
ethis.props.history.push
.fonte
Para usar
withRouter
com um componente baseado em classe, tente algo como isto abaixo. Não se esqueça de alterar a instrução de exportação para usarwithRouter
:import { withRouter } from 'react-router-dom'
fonte
com base na resposta anterior
de José Antonio Postigo e Ben Wheeler
a novidade? deve ser escrito em Texto Dactilografado
e o uso de decoradores
OU propriedade / campo estático
com qualquer npm instalado hoje. "react-router": "^ 3.0.0" e
"@ types / react-router": "^ 2.0.41"
fonte
com o React-Router v4 no horizonte, agora existe uma nova maneira de fazer isso.
O react-lego é um exemplo de aplicativo que mostra como usar / atualizar o reag-router e inclui exemplos de testes funcionais que navegam no aplicativo.
fonte
No roteador de reação v4. Eu sigo estas duas maneiras de rotear programaticamente.
Número dois
Para obter histórico de adereços, você pode precisar envolver seu componente com
fonte
Se você estiver usando o hash ou o histórico do navegador, poderá fazer
fonte
hashHistory.push
, fornece Não é possível ler a propriedade "push" de indefinido. De onde você os importa?Com a versão atual do React (15.3),
this.props.history.push('/location');
funcionou para mim, mas mostrou o seguinte aviso:e eu resolvi usando
context.router
assim:fonte
React-Router V4
se você estiver usando a versão 4, poderá usar minha biblioteca (plugue Shameless), onde você simplesmente despacha uma ação e tudo funciona!
trippler
fonte
Aqueles que estão enfrentando problemas ao implementá-lo no react-router v4.
Aqui está uma solução funcional para navegar pelo aplicativo de reação a partir de ações de redux.
history.js
App.js / Route.jsx
another_file.js OU arquivo redux
Tudo graças a este comentário: ReactTraining issues comment
fonte
Se, por acaso, emparelhar RR4 com redux com react -router-redux , use também as
react-router-redux
opções de ação de roteamento .Se usar redux thunk / saga para gerenciar o fluxo assíncrono, importe os criadores da ação acima em ações redux e conecte-os a reagir componentes usando o mapDispatchToProps, que pode ser melhor.
fonte
react-router-redux
foi preterido / arquivados por um longo tempoVocê também pode usar o
useHistory
gancho em um componente sem estado. Exemplo dos documentos.fonte
A resposta certa foi para mim no momento em que escrevi
Mas você precisa adicionar PropTypes ao seu componente
Não se esqueça de importar PropTypes
fonte
Talvez não seja a melhor solução, mas faz o trabalho:
Basicamente, uma lógica vinculada a uma ação (nesse caso, uma exclusão posterior) acabará chamando um gatilho para redirecionamento. Isso não é ideal, pois você adicionará um 'gatilho' do nó DOM à sua marcação para poder chamá-lo convenientemente quando necessário. Além disso, você interagirá diretamente com o DOM, o que em um componente React pode não ser desejado.
Ainda assim, esse tipo de redirecionamento não é necessário com tanta frequência. Portanto, um ou dois links ocultos extras na sua marcação de componente não prejudicariam tanto, especialmente se você lhes der nomes significativos.
fonte
Isso funcionou para mim, nenhuma importação especial necessária:
fonte
history
adicionadoprops
apenas por si só. Que vem de um hoc, que você precisaria de importação, a fim de uso (componentes enviada diretamente para porRoute
são automaticamente envolto por essa hoc, mas então você precisa de uma importação paraRoute
...)use hookrouter, a alternativa moderna ao reag-router
https://www.npmjs.com/package/hookrouter
Para responder à pergunta do OP sobre como vincular através da caixa de seleção, você pode fazê-lo:
fonte
Supondo que você não precise navegar durante a renderização inicial em si (para a qual você pode usar
<Redirect>
componente), é isso que estamos fazendo em nosso aplicativo.Defina uma rota vazia que retorne nulo; isso permitirá que você obtenha acesso ao objeto histórico. Você precisa fazer isso no nível superior, onde
Router
está definido.Agora você pode fazer tudo o que pode ser feito na história
history.push()
, comohistory.replace()
,history.go(-1)
etc!fonte
react-router-dom: 5.1.2
Este site possui 3 páginas, todas renderizadas dinamicamente no navegador.
Embora a página nem sempre seja atualizada, observe como o React Router mantém o URL atualizado enquanto você navega no site. Isso preserva o histórico do navegador, garantindo que coisas como o botão Voltar e os favoritos funcionem corretamente
Um Switch examina todos os elementos filhos e renderiza o primeiro cujo caminho corresponde ao URL atual. Use sempre que houver várias rotas, mas você deseja que apenas uma delas seja renderizada por vez
fonte
Portanto, na minha resposta, existem três maneiras diferentes de redirecionar programaticamente para uma rota. Algumas das soluções já foram apresentadas, mas as seguintes focaram apenas em componentes funcionais com um aplicativo de demonstração adicional.
Usando as seguintes versões:
Configuração:
Então, antes de tudo, a solução está usando
HashRouter
, configurada da seguinte maneira:A partir da documentação sobre
<HashRouter>
:Soluções:
<Redirect>
para empurrar usandouseState
:Usando em um componente funcional (
RedirectPushAction
componente do meu repositório), podemos usaruseState
para manipular o redirecionamento. A parte complicada é que, uma vez que o redirecionamento aconteceu, precisamos definir oredirect
estado novamentefalse
. UsandosetTimeOut
com0
atraso, estamos aguardando até que o React confirmeRedirect
no DOM e depois retorne o botão para usar na próxima vez.Por favor, encontre meu exemplo abaixo:
Da
<Redirect>
documentação:useHistory
gancho:Na minha solução, há um componente chamado
UseHistoryAction
que representa o seguinte:withRouter
, obtenha ohistory
deprops
:Criado um componente chamado
WithRouterAction
, é exibido como abaixo:Leitura da
withRouter
documentação:Demo:
Para uma melhor representação, criei um repositório GitHub com estes exemplos, por favor, encontre-o abaixo:
https://github.com/norbitrial/react-router-programmatically-redirect-examples
Eu espero que isso ajude!
fonte