hashrouter - ¿Cómo escuchar los cambios de ruta en react router v4?
react-router-dom redirect (6)
Tengo un par de botones que actúan como rutas. Cada vez que se cambia la ruta, quiero asegurarme de que el botón que está activo cambia.
¿Hay alguna manera de escuchar los cambios de ruta en react router v4?
Con ganchos:
class App extends React.Component {
constructor (props) {
super(props);
}
onRouteChange (pageId) {
console.log(pageId);
}
render () {
return <Switch>
<Route path="/" exact render={(props) => {
this.onRouteChange(''home'');
return <HomePage {...props} />;
}} />
<Route path="/checkout" exact render={(props) => {
this.onRouteChange(''checkout'');
return <CheckoutPage {...props} />;
}} />
</Switch>
}
}
Importar y renderizar como componente
<DebugHistory>
Deberías usar el historial v4 lib.
Ejemplo a partir de there
history.listen((location, action) => {
console.log(`The current URL is ${location.pathname}${location.search}${location.hash}`)
console.log(`The last navigation action was ${action}`)
})
En algunos casos, puede usar el atributo
render
lugar del
component
, de esta manera:
import { useEffect } from ''react''
import { withRouter } from ''react-router-dom''
import { history as historyShape } from ''react-router-prop-types''
const DebugHistory = ({ history }) => {
useEffect(() => {
console.log(''> Router'', history.action, history.location])
}, [history.location.key])
return null
}
DebugHistory.propTypes = { history: historyShape }
export default withRouter(DebugHistory)
Tenga en cuenta que si cambia de estado en el método
onRouteChange
, esto podría causar el error ''Profundidad máxima de actualización excedida''.
Para ampliar lo anterior, deberá acceder al objeto de historial.
Si está utilizando
BrowserRouter
, puede importar
withRouter
y envolver su componente con un
componente de orden superior (HoC)
para tener acceso mediante accesorios a las propiedades y funciones del objeto de historial.
import { withRouter } from ''react-router-dom'';
const myComponent = ({ history }) => {
history.listen((location, action) => {
// location is an object like window.location
console.log(action, location.pathname, location.state)
});
return <div>...</div>;
};
export default withRouter(myComponent);
Lo único que debe tener en cuenta es que con Router y la mayoría de las otras formas de acceder a la
history
parecen contaminar los accesorios a medida que desestructuran el objeto en él.
Utilizo
withRouter
para obtener el accesorio de
location
.
Cuando el componente se actualiza debido a una nueva ruta, verifico si el valor cambió:
@withRouter
class App extends React.Component {
static propTypes = {
location: React.PropTypes.object.isRequired
}
// ...
componentDidUpdate(prevProps) {
if (this.props.location !== prevProps.location) {
this.onRouteChanged();
}
}
onRouteChanged() {
console.log("ROUTE CHANGED");
}
// ...
render(){
return <Switch>
<Route path="/" exact component={HomePage} />
<Route path="/checkout" component={CheckoutPage} />
<Route path="/success" component={SuccessPage} />
// ...
<Route component={NotFound} />
</Switch>
}
}
Espero eso ayude
withRouter
,
history.listen
y
useEffect
(React Hooks) funcionan bastante bien juntos:
const Component = ({ history }) => { useEffect(() => history.listen(() => { // do something on route change // for my example, close a drawer }), []) //... } export default withRouter(Component)
La devolución de llamada de escucha se activará cada vez que se cambie una ruta, y el retorno para
history.listen
es un controlador de apagado que funciona muy bien con
useEffect
.