react-router-dom: getting props.location from within component

前端 未结 4 1279
野的像风
野的像风 2021-02-20 14:03

I have a simple App that uses BrowserRouter from \'react-router-dom\' v4. I\'m trying to access the location.pathname property from within the &l

相关标签:
4条回答
  • 2021-02-20 14:22

    After digging through their GitHub issues, I found the solution. I must render a <Route /> within <BrowserRouter /> and pass the rest of my app into its render() function with history as a parameter. Within the render function, I can find the app's location in history.location.pathname.

    class App extends Component{
      render(){
        return (
          <BrowserRouter>
    
            // We must add a parent <Route> and render its children while passing 'history' as parameter
            <Route path={Paths.reserve} render={(history) => 
    
              // Within render(), we can find it in history.location.pathname
              <div className={(history.location.pathname === "/account") ? "background-black" : "background-white"} >
                <Switch>
                  <Route path="/login" component={LoginPage}/>
                  <Route path="/success" component={LoginSuccess}/>
                  <Route path="/account" component={MyAccount}/>
                  ...
                  <Route component={Error404}/>
                </Switch>
              </div>
              }/>
            }} />
          </BrowserRouter>
        );
      }
    }
    

    This will update the history parameter automatically, without having to re-render on componentDidMount() or componentDidUpdate()

    0 讨论(0)
  • 2021-02-20 14:24

    Since react-router v5.1.0 you can use useLocation.

    https://reactrouter.com/web/api/Hooks/uselocation

    class App extends Component{
      render(){
        const location = useLocation();
    
        return (
          <div className={(location.pathname === "/account") ? "bgnd-black" : "bgnd-white"} >
            //...
          </div>
        );
      }
    }
    
    // ...
    <BrowserRouter>
      <App />
    </BrowserRouter>
    
    0 讨论(0)
  • 2021-02-20 14:26

    You can also do it using withRouter which has a similar result to putting the code in a render parameter and avoids the need for a "fake" <Route/>.

    Essentially you put the JSX that needs to know the location in a component of its own, which is wrapped by withRouter. This supplies the location to the component:

    import { withRouter } from 'react-router-dom';
    
    const Content = withRouter(props =>
        <div className={(props.location.pathname === "/account") ? "backg...
        ...
        </div>
    );
    

    Then you use that in your main router section:

    class App extends Component{
        render() {
            return (
                <BrowserRouter>
                    <Content/>
                    ...
    
    0 讨论(0)
  • 2021-02-20 14:38

    You achieve what u have asked for by doing this

    import AccessRoute from './AccessRoute'
    
    class App extends Component{
      render(){
        return (
          <BrowserRouter>
    
      <AccessRoute>    
     <div className={(this.props.location.pathnme === "/account") ? "bgnd-black" : "bgnd-white"} >
              <Switch>
                <Route path="/login" component={LoginPage}/>
                <Route path="/success" component={LoginSuccess}/>
                <Route path="/account" component={MyAccount}/>
                ...
                <Route component={Error404}/>
              </Switch>
            </div>
           </AccessRoute>    
          </BrowserRouter>
        );
      }
    }
    

    AccessRoute.jsx

    import React from 'react'
    import {withRouter} from 'react-router';
    class AccessRoute extends React.Component{
        constructor(props){
            super(props);
        }
    
    
    
     //If you want to find the location on mount use this 
    
     componentDidMount(){
            console.log("the path name is ",this.props.location.pathname);
        }
    
    
     //If you want to find the location on change use this
    
      componentDidUpdate(prevprops){
        if(this.props.location.pathname!=prevprops.location.pathname){
            console.log("the new path name is ",this.props.location.pathname);
        }
    
    }
    
        render(){
            return(
    
                this.props.children
    
                );
        }
    }
    export default withRouter(AccessRoute)
    
    0 讨论(0)
提交回复
热议问题