【问题标题】:react-router-dom: getting props.location from within <BrowserRouter> componentreact-router-dom:从 <BrowserRouter> 组件中获取 props.location
【发布时间】:2018-04-28 03:24:25
【问题描述】:

我有一个简单的应用程序,它使用来自 'react-router-dom' v4 的 BrowserRouter。我试图从&lt;BrowserRouter/&gt; 组件中访问location.pathname 属性,但无济于事:

class App extends Component{
  render(){
    return (
      <BrowserRouter>
        // How do I access this.props.location?
        <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>
      </BrowserRouter>
    );
  }
}

我知道我可以使用this.props.location.pathname 通过子组件访问应用程序的当前路径位置,但我需要从父组件访问它,就在&lt;BrowserRouter/&gt; 的下方,以运行与子组件无关的附加逻辑成分。我怎样才能得到这个位置?

【问题讨论】:

    标签: reactjs react-router-dom


    【解决方案1】:

    您也可以使用withRouter 执行此操作,其结果与将代码放入render 参数中的结果相似,并且无需“假”&lt;Route/&gt;

    本质上,您将需要知道位置的 JSX 放在它自己的组件中,该组件由 withRouter 包装。这将位置提供给组件:

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

    然后你在你的主路由器部分使用它:

    class App extends Component{
        render() {
            return (
                <BrowserRouter>
                    <Content/>
                    ...
    

    【讨论】:

    • 这是迄今为止我见过的最简洁的答案。
    • 非常好的答案。谢谢@Malvineous
    【解决方案2】:

    由于react-router v5.1.0,您可以使用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>
    

    【讨论】:

    • 是的,这是一个非常好的解决方案。谢谢。
    【解决方案3】:

    在挖掘了他们的 GitHub 问题后,我找到了解决方案。我必须在&lt;BrowserRouter /&gt; 中渲染一个&lt;Route /&gt;,并将我的应用程序的其余部分传递给它的render() 函数,并以history 作为参数。在渲染函数中,我可以在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>
        );
      }
    }
    

    这将自动更新history 参数,而无需在componentDidMount()componentDidUpdate() 上重新渲染

    【讨论】:

    • 'react-router-dom' 不包含名为 'Paths' 的导出
    • @Reft 不,它没有。 Paths 是我自己的对象。
    • 所以我使用了这种方法,在让 ReactTransitionGroup 与它一起运行时遇到问题,我认为当顶级路由触发状态更改时,CSSTransition 组件的状态或生命周期会被弄乱。
    【解决方案4】:

    通过这样做,您实现了您的要求

    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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-17
      • 2021-11-30
      • 2019-11-09
      • 2018-02-07
      • 2018-12-04
      • 2019-07-27
      相关资源
      最近更新 更多