Reputation: 453
Is there any way to fire an event when route changes with react router v4. I need to fire a function on every route change. I use BrowserRouter
and Switch
from react-router-dom
on client side in universal react-redux application.
Upvotes: 4
Views: 13841
Reputation: 2704
React: v15.x, React Router: v4.x
components/core/App.js:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { BrowserRouter } from 'react-router-dom';
class LocationListener extends Component {
static contextTypes = {
router: PropTypes.object
};
componentDidMount() {
this.handleLocationChange(this.context.router.history.location);
this.unlisten =
this.context.router.history.listen(this.handleLocationChange);
}
componentWillUnmount() {
this.unlisten();
}
handleLocationChange(location) {
// your staff here
console.log(`- - - location: '${location.pathname}'`);
}
render() {
return this.props.children;
}
}
export class App extends Component {
...
render() {
return (
<BrowserRouter>
<LocationListener>
...
</LocationListener>
</BrowserRouter>
);
}
}
index.js:
import App from 'components/core/App';
render(<App />, document.querySelector('#root'));
Upvotes: 5
Reputation: 714
I resolved this by wrapping my application with an additional component. That component is used in a Route
so it also has access to the history
prop.
<BrowserRouter>
<Route component={App} />
</BrowserRouter>
The App
component subscribes on history changes, so I can do something whenever the route changes:
export class App extends React.Component {
componentWillMount() {
const { history } = this.props;
this.unsubscribeFromHistory = history.listen(this.handleLocationChange);
this.handleLocationChange(history.location);
}
componentWillUnmount() {
if (this.unsubscribeFromHistory) this.unsubscribeFromHistory();
}
handleLocationChange = (location) => {
// Do something with the location
}
render() {
// Render the rest of the application with its routes
}
}
Not sure if this is the right way to do it in V4, but I didn't find any other extensibility points on the router itself, so this seems to work instead. Hope that helps.
Edit: Perhaps you could also achieve the same goal by wrapping <Route />
in your own component and using something like componentWillUpdate
to detect location changes.
Upvotes: 10