我想在<AppBar />中显示一个标题,该标题以某种方式从当前路由传递进来。

在React Router v4中,<AppBar />如何能够将当前路由传递到它的标题道具中?

  <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>

是否有一种方法从<Route />上的自定义道具传递自定义标题?


当前回答

I think the author's of React Router (v4) just added that withRouter HOC to appease certain users. However, I believe the better approach is to just use render prop and make a simple PropsRoute component that passes those props. This is easier to test as you it doesn't "connect" the component like withRouter does. Have a bunch of nested components wrapped in withRouter and it's not going to be fun. Another benefit is you can also use this pass through whatever props you want to the Route. Here's the simple example using render prop. (pretty much the exact example from their website 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 } />

其他回答

在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>
  );
}

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}`)

这里有一个使用历史的解决方案阅读更多

import { createBrowserHistory } from "history";

const history = createBrowserHistory()

在路由器

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

如果你正在使用react的模板,你的react文件的结尾看起来像这样:导出默认的SomeComponent,你需要使用更高阶的组件(通常称为“HOC”),与throuter。

首先,你需要像这样用throuter导入:

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

接下来,您将希望使用withthrouter。您可以通过更改组件的导出来实现这一点。您可能希望将导出默认的ComponentName更改为使用throuter (ComponentName)导出默认。

然后你可以从道具中获得路线(和其他信息)。具体来说,是位置、匹配和历史。输出路径名的代码是:

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

你可以在这里找到一篇包含更多信息的文章:https://reacttraining.com/react-router/core/guides/philosophy

在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>
}