How to listen to route changes in react router v4?

ID : 20223

viewed : 26

Tags : react-router-v4react-router-v4

Top 5 Answer for How to listen to route changes in react router v4?

vote vote

92

I use withRouter to get the location prop. When the component is updated because of a new route, I check if the value changed:

@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>   } } 

Hope it helps

vote vote

85

To expand on the above, you will need to get at the history object. If you are using BrowserRouter, you can import withRouter and wrap your component with a higher-order component (HoC) in order to have access via props to the history object's properties and functions.

    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); 

The only thing to be aware of is that withRouter and most other ways to access the history seem to pollute the props as they de-structure the object into it.

As others have said, this has been superseded by the hooks exposed by react router and it has a memory leak. If you are registering listeners in a functional component you should be doing so via useEffect and unregistering them in the return of that function.

vote vote

73

v5.1 introduces the useful hook useLocation

https://reacttraining.com/blog/react-router-v5-1/#uselocation

import { Switch, useLocation } from 'react-router-dom'  function usePageViews() {   let location = useLocation()    useEffect(     () => {       ga.send(['pageview', location.pathname])     },     [location]   ) }  function App() {   usePageViews()   return <Switch>{/* your routes here */}</Switch> } 
vote vote

65

You should to use history v4 lib.

Example from 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}`) }) 
vote vote

55

withRouter, history.listen, and useEffect (React Hooks) works quite nicely together:

import React, { useEffect } from 'react' import { withRouter } from 'react-router-dom'  const Component = ({ history }) => {     useEffect(() => history.listen(() => {         // do something on route change         // for my example, close a drawer     }), [])      //... }  export default withRouter(Component) 

The listener callback will fire any time a route is changed, and the return for history.listen is a shutdown handler that plays nicely with useEffect.

Top 3 video Explaining How to listen to route changes in react router v4?

Related QUESTION?