【问题标题】:React Router v4 - How to get current route?React Router v4 - 如何获取当前路由?
【发布时间】:2018-12-13 13:55:51
【问题描述】:

我想在<AppBar /> 中显示一个title,它以某种方式从当前路由传入。

在 React Router v4 中,<AppBar /> 如何能够将当前路由传递到它的 title 属性中?

  <Router basename='/app'>
    <main>
      <Menu active={menu} close={this.closeMenu} />
      <Overlay active={menu} onClick={this.closeMenu} />
      <AppBar handleMenuIcon={this.handleMenuIcon} title='Test' />
      <Route path='/customers' component={Customers} />
    </main>
  </Router>

有没有办法从&lt;Route /&gt; 上的自定义prop 传递自定义标题?

【问题讨论】:

标签: reactjs react-router react-router-v4


【解决方案1】:

在反应路由器 4 中,当前路由位于 - this.props.location.pathname。 只需获取this.props 并验证即可。 如果您仍然看不到location.pathname,那么您应该使用装饰器withRouter

这可能看起来像这样:

import {withRouter} from 'react-router-dom';

const SomeComponent = withRouter(props => <MyComponent {...props}/>);

class MyComponent extends React.Component {
  SomeMethod () {
    const {pathname} = this.props.location;
  }
}

【讨论】:

  • 请注意,这并不总是正确的:使用 react-router4 ,如果您的组件相对于某些嵌套路由(稍后扩展路径)在更高级别上呈现,则 WithRouter 中的 location.pathname 将不同于window.location.pathname
  • 我们如何在 React 组件之外以编程方式获取它?
  • 此解决方案未提供如何在包含 本身的组件中使用这些道具。
【解决方案2】:

我认为 React Router (v4) 的作者只是添加了 withRouter HOC 来安抚某些用户。但是,我相信更好的方法是只使用渲染道具并制作一个简单的 PropsRoute 组件来传递这些道具。这更容易测试,因为它不像 withRouter 那样“连接”组件。将一堆嵌套组件包裹在 withRouter 中,这不会很有趣。另一个好处是你也可以通过你想要的任何道具来使用这个通道。这是使用渲染道具的简单示例。 (几乎是他们网站https://reacttraining.com/react-router/web/api/Route/render-func的确切示例) (src/components/routes/props-route)

import React from 'react';
import { Route } from 'react-router';

export const PropsRoute = ({ component: Component, ...props }) => (
  <Route
    { ...props }
    render={ renderProps => (<Component { ...renderProps } { ...props } />) }
  />
);

export default PropsRoute;

用法:(注意获取路由参数(match.params)你可以使用这个组件,这些将被传递给你)

import React from 'react';
import PropsRoute from 'src/components/routes/props-route';

export const someComponent = props => (<PropsRoute component={ Profile } />);

还请注意,您也可以通过这种方式传递任何您想要的额外道具

<PropsRoute isFetching={ isFetchingProfile } title="User Profile" component={ Profile } />

【讨论】:

  • 有什么办法可以把这个解决方案变成一个codepen?我想用更正确的解决方案,但我真的不明白如何实现。
【解决方案3】:

如果您使用的是 react 的模板,那么您的 react 文件的结尾如下所示:export default SomeComponent 您需要使用高阶组件(通常称为“HOC”)withRouter

首先,您需要像这样导入withRouter

import {withRouter} from 'react-router-dom';

接下来,您需要使用 withRouter。您可以通过更改组件的导出来做到这一点。您可能想从 export default ComponentName 更改为 export default withRouter(ComponentName)

然后你可以从 props 中获取路线(和其他信息)。具体来说,locationmatchhistory。吐出路径名的代码是:

console.log(this.props.location.pathname);

此处提供了包含更多信息的优秀文章:https://reacttraining.com/react-router/core/guides/philosophy

【讨论】:

  • 但是如何获得完整的 url?
【解决方案4】:

这是使用historyRead more的解决方案

import { createBrowserHistory } from "history";

const history = createBrowserHistory()

在路由器内部

<Router>
   {history.location.pathname}
</Router>

【讨论】:

  • 对于我们这些在 react 函数路径上的人来说,这个答案是最有意义的。那些this.props.... 对我们来说只是噪音。
  • 这是唯一直接在 标签内工作的解决方案,没有子组件或直接使用文档/窗口位置。
【解决方案5】:

Con Posidielov 说过,当前路线存在于this.props.location.pathname

但是如果你想匹配一个更具体的字段,比如一个键(或一个名字),你可以使用matchPath 来查找原始路由参考。

import { matchPath } from `react-router`

const routes = [{
  key: 'page1'
  exact: true,
  path: '/page1/:someparam/',
  component: Page1,
},
{
  exact: true,
  key: 'page2',
  path: '/page2',
  component: Page2,
},
]

const currentRoute = routes.find(
  route => matchPath(this.props.location.pathname, route)
)

console.log(`My current route key is : ${currentRoute.key}`)

【讨论】:

    【解决方案6】:

    react-router v5中有一个叫useLocation的钩子,不需要HOC之类的东西,非常简洁方便。

    import { useLocation } from 'react-router-dom';
    
    const ExampleComponent: React.FC = () => {
      const location = useLocation();  
    
      return (
        <Router basename='/app'>
          <main>
            <AppBar handleMenuIcon={this.handleMenuIcon} title={location.pathname} />
          </main>
        </Router>
      );
    }
    

    【讨论】:

    • 这个答案应该得到更高的评价。使用钩子比这些其他解决方案更容易和直观(如果在 RR v5 上)
    • 这是 RR v5 的当前答案
    【解决方案7】:

    添加

    import {withRouter} from 'react-router-dom';
    

    然后更改您的组件导出

    export default withRouter(ComponentName)
    

    然后,您可以使用以下方式直接在组件本身内访问路由(无需触及项目中的任何其他内容):

    window.location.pathname
    

    测试于 2020 年 3 月:“版本”:“5.1.2”

    【讨论】:

    • 不确定这个。当然,它给出了当前路径名,但如果我导航到新页面,这不会改变。
    【解决方案8】:

    在 react-router 的 5.1 版本中有一个叫做 useLocation 的钩子,它返回当前的位置对象。这在您需要知道当前 URL 的任何时候都可能有用。

    import { useLocation } from 'react-router-dom'
    
    function HeaderView() {
      const location = useLocation();
      console.log(location.pathname);
      return <span>Path : {location.pathname}</span>
    }
    
    

    【讨论】:

    • 请注意,这只能在Router DOM内部使用(即chid组件,不能在使用Router的类/功能组件中)。这可能很明显,但对于像我这样的新手来说却不是:-) 我一直收到错误“useContext is undefined”
    • 如果使用了路由器redirect,这也将不起作用。这将读取重定向之前的路径
    • 为什么不将位置设置为const 而不是let,因为我们知道它在这种情况下不会改变?
    • 非常适合单元测试兼容性,避免模拟 window.location
    猜你喜欢
    • 2018-11-03
    • 2017-09-10
    • 2018-08-01
    • 2016-05-04
    • 2016-11-27
    • 2021-05-21
    • 2018-01-18
    • 1970-01-01
    相关资源
    最近更新 更多