Eu tenho alguns botões que funcionam como rotas. Sempre que a rota é alterada, quero garantir que o botão ativo seja alterado.
Existe uma maneira de ouvir as alterações de rota no roteador de reação v4?
react-router-v4
Kasper
fonte
fonte
Respostas:
Eu uso
withRouter
para pegar olocation
suporte. Quando o componente é atualizado devido a uma nova rota, verifico se o valor mudou:Espero que ajude
fonte
withRouter
, mas estou recebendo erroYou should not use <Route> or withRouter() outside a <Router>
. Não vejo nenhum<Router/>
componente no código acima. Então, como está funcionando?<Switch>
componente está agindo como o roteador de fato. Somente a primeira<Route>
entrada a ter um caminho correspondente será renderizada. Não há necessidade de qualquer<Router/>
componente neste cenárioPara expandir o exposto, você precisará acessar o objeto de histórico. Se você estiver usando
BrowserRouter
, poderá importarwithRouter
e agrupar seu componente com um componente de ordem superior (HoC) para ter acesso via adereços às propriedades e funções do objeto de histórico.A única coisa a ter em mente é que, com o Router e a maioria das outras maneiras de acessar,
history
parece poluir os objetos à medida que desestruturam o objeto nele.fonte
withRoutes
awithRouter
.history
em vez da variávellisten
.Você deve usar o histórico v4 lib.
Exemplo de lá
fonte
history.push
isso disparahistory.listen
. Consulte o exemplo Usando um URL base nos documentos da história v4 . Como essehistory
é realmente um invólucro dohistory
objeto nativo de um navegador, ele não se comporta exatamente como o nativo.const unlisten = history.listen(myListener); unlisten();
withRouter
,history.listen
EuseEffect
(Reagir Hooks) funciona muito bem em conjunto:O retorno de chamada do ouvinte será acionado sempre que uma rota for alterada e o retorno de
history.listen
for um manipulador de desligamento que funcione bemuseEffect
.fonte
v5.1 introduz o gancho útil
useLocation
https://reacttraining.com/blog/react-router-v5-1/#uselocation
fonte
Cannot read property 'location' of undefined at useLocation
. Você precisa garantir que a chamada useLocation () não esteja no mesmo componente que coloca o roteador na árvore: veja aquiCom ganchos:
Importar e renderizar como
<DebugHistory>
componentefonte
com ganchos
fonte
fonte
Com react Hooks, estou usando
useEffect
fonte
Em alguns casos, você pode usar o
render
atributo em vez decomponent
, desta maneira:Observe que, se você alterar o estado no
onRouteChange
método, isso poderá causar o erro 'Profundidade máxima de atualização excedida'.fonte
Com o
useEffect
gancho, é possível detectar alterações de rota sem adicionar um ouvinte.fonte
Como acabei de lidar com esse problema, adicionarei minha solução como um complemento às outras respostas fornecidas.
O problema aqui é que
useEffect
realmente não funciona como você gostaria, pois a chamada só é acionada após a primeira renderização, para que haja um atraso indesejado.Se você usar algum gerente de estado como o redux, é provável que ocorra uma cintilação na tela por causa do estado remanescente na loja.
O que você realmente deseja é usar,
useLayoutEffect
pois isso é acionado imediatamente.Então, escrevi uma pequena função utilitária que coloquei no mesmo diretório do meu roteador:
Que eu chamo de dentro do componente HOC assim:
path
é o suporte que é passado nomatch
objeto durante o usowithRouter
.Eu realmente não sou a favor de ouvir / não ouvir manualmente na história. Isso é apenas imo.
fonte