Detect Route Change with react-router

前端 未结 8 929
南笙
南笙 2020-11-27 11:18

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

What I want to do is something like this:

reactRouter.onUrlChange(url => {
         


        
相关标签:
8条回答
  • 2020-11-27 12:12

    react-router v6

    In the upcoming v6, this can be done by combining the useLocation and useEffect hooks

    import { useLocation } from 'react-router-dom';
    
    const MyComponent = () => {
      const location = useLocation()
    
      React.useEffect(() => {
        // runs on location, i.e. route, change
        console.log('handle route change here', location)
      }, [location])
      ...
    }
    

    For convenient reuse, you can do this in a custom useLocationChange hook

    // runs action(location) on location, i.e. route, change
    const useLocationChange = (action) => {
      const location = useLocation()
      React.useEffect(() => { action(location) }, [location])
    }
    
    const MyComponent1 = () => {
      useLocationChange((location) => { 
        console.log('handle route change here', location) 
      })
      ...
    }
    
    const MyComponent2 = () => {
      useLocationChange((location) => { 
        console.log('and also here', location) 
      })
      ...
    }
    

    If you also need to see the previous route on change, you can combine with a usePrevious hook

    const usePrevious(value) {
      const ref = React.useRef()
      React.useEffect(() => { ref.current = value })
    
      return ref.current
    }
    
    const useLocationChange = (action) => {
      const location = useLocation()
      const prevLocation = usePrevious(location)
      React.useEffect(() => { 
        action(location, prevLocation) 
      }, [location])
    }
    
    const MyComponent1 = () => {
      useLocationChange((location, prevLocation) => { 
        console.log('changed from', prevLocation, 'to', location) 
      })
      ...
    }
    

    It's important to note that all the above fire on the first client route being mounted, as well as subsequent changes. If that's a problem, use the latter example and check that a prevLocation exists before doing anything.

    0 讨论(0)
  • 2020-11-27 12:19

    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>
            )
        }
    } 
    
    0 讨论(0)
提交回复
热议问题