Detect Route Change with react-router

2019-01-10 19:23发布

I have to implement some business logic depending on browsing history.

What I want to do is something like this:

reactRouter.onUrlChange(url => {
   this.history.push(url);
});

Is there any way to receive a callback from react-router when the URL gets updated?

2条回答
爷的心禁止访问
2楼-- · 2019-01-10 19:38

If you want to listen to the history object globally, you'll have to create it yourself and pass it to the Router. Then you can listen to it with its listen() method:

// Use Router from react-router, not BrowserRouter.
import { Router } from 'react-router';

// Create history object.
import createHistory from 'history/createBrowserHistory';
const history = createHistory();

// Listen to history changes.
// You can unlisten by calling the constant (`unlisten()`).
const unlisten = history.listen((location, action) => {
  console.log(action, location.pathname, location.state);
});

// Pass history to Router.
<Router history={history}>
   ...
</Router>

Even better if you create the history object as a module, so you can easily import it anywhere you may need it (e.g. import history from './history';

查看更多
\"骚年 ilove
3楼-- · 2019-01-10 19:42

You can make use of history.listen() function when trying to detect the route change. Considering you are using react-router v4, wrap your component with withRouter HOC to get access to the history prop.

history.listen() returns an unlisten function. You'd use this to unregister from listening.

You can configure your routes like

index.js

ReactDOM.render(
      <BrowserRouter>
            <AppContainer>
                   <Route exact path="/" Component={...} />
                   <Route exact path="/Home" Component={...} />
           </AppContainer>
        </BrowserRouter>,
  document.getElementById('root')
);

and then in AppContainer.js

class App extends Component {

  componentWillMount() {
    this.unlisten = this.props.history.listen((location, action) => {
      console.log("on route change");
    });
  }
  componentWillUnmount() {
      this.unlisten();
  }
  render() {
     return (
         <div>{this.props.children}</div>
      );
  }
}
export default withRouter(App);

From the history docs:

You can listen for changes to the current location using history.listen:

history.listen((location, action) => {
      console.log(`The current URL is ${location.pathname}${location.search}${location.hash}`)
  console.log(`The last navigation action was ${action}`)
})

The location object implements a subset of the window.location interface, including:

**location.pathname** - The path of the URL
**location.search** - The URL query string
**location.hash** - The URL hash fragment

Locations may also have the following properties:

location.state - Some extra state for this location that does not reside in the URL (supported in createBrowserHistory and createMemoryHistory)

location.key - A unique string representing this location (supported in createBrowserHistory and createMemoryHistory)

The action is one of PUSH, REPLACE, or POP depending on how the user got to the current URL.

When you are using react-router v3 you can make use of history.listen() from history package as mentioned above or you can also make use browserHistory.listen()

You can configure and use your routes like

import {browserHistory} from 'react-router';

class App extends React.Component {

    componentDidMount() {
          this.unlisten = browserHistory.listen( location =>  {
                console.log('route changes');

           });

    }
    componentWillUnmount() {
        this.unlisten();

    }
    render() {
        return (
               <Route path="/" onChange={yourHandler} component={AppContainer}>
                   <IndexRoute component={StaticContainer}  />
                   <Route path="/a" component={ContainerA}  />
                   <Route path="/b" component={ContainerB}  />
            </Route>
        )
    }
} 
查看更多
登录 后发表回答