react-router在子组件中获取this.props.location


80

据我了解,<Route path="/" component={App} />会提供App与路由相关的道具,例如locationparams。如果我的App组件有许多嵌套的子组件,那么我如何在不使用以下子项的情况下让子组件访问这些道具:

  • 从App传递道具
  • 使用窗口对象
  • 为嵌套的子组件创建路线

我以为this.context.router会有一些与路线有关的信息,但this.context.router似乎只有一些功能可以操纵路线。


在App Component中,可以在this.props.children
gu mingfeng '16

Answers:


137

(更新)V5.1和挂钩(需要React> = 16.8)

您可以使用useHistoryuseLocationuseRouteMatch在你的组件来获得matchhistorylocation

const Child = () => {
  const location = useLocation();
  const history = useHistory();
  const match = useRouteMatch("write-the-url-you-want-to-match-here");

  return (
    <div>{location.pathname}</div>
  )
}

export default Child

(更新)V4和V5

您可以使用withRouter,以HOC注入matchhistorylocation在组件的道具。

class Child extends React.Component {
  static propTypes = {
    match: PropTypes.object.isRequired,
    location: PropTypes.object.isRequired,
    history: PropTypes.object.isRequired
  }

  render() {
    const { match, location, history } = this.props

    return (
      <div>{location.pathname}</div>
    )
  }
}

export default withRouter(Child)

(更新)V3

您可以使用withRouterHOC以注入routerparamslocationroutes在组件中的道具。

class Child extends React.Component {

  render() {
    const { router, params, location, routes } = this.props

    return (
      <div>{location.pathname}</div>
    )
  }
}

export default withRouter(Child)

原始答案

如果您不想使用道具,则可以使用React Router文档中所述的上下文

首先,你必须设置你的childContextTypesgetChildContext

class App extends React.Component{

  getChildContext() {
    return {
      location: this.props.location
    }
  }

  render() {
    return <Child/>;
  }
}

App.childContextTypes = {
    location: React.PropTypes.object
}

然后,您将可以使用如下上下文访问子组件中的location对象

class Child extends React.Component{

   render() {
     return (
       <div>{this.context.location.pathname}</div>
     )
   }

}

Child.contextTypes = {
    location: React.PropTypes.object
 }

谢谢你的指导。我没有阅读文档的那部分。我以为只有context.router
xiaofan2406


3
我是React的新手。因此,如果我错了,请原谅我,但是使用错了window.location.pathname什么?
Artur Barseghyan

1
window.location是可变的,因此最好使用不可变版本,而不是访问它。另外,我认为可以使用与window.location不同的逻辑位置(至少在nextjs中是这样),因此可以从路由器获得的位置与直接窗口历史记录不同的位置
Chanoch

@ArturBarseghyanwindow如果React代码在服务器上运行(例如,实现服务器端路由),则该对象不存在。
ChrisW

4

如果上述解决方案不适合您,则可以使用 import { withRouter } from 'react-router-dom';


使用此方法,您可以将您的子类导出为-

class MyApp extends Component{
    // your code
}

export default withRouter(MyApp);

而您的路由器课程-

// your code
<Router>
      ...
      <Route path="/myapp" component={MyApp} />
      // or if you are sending additional fields
      <Route path="/myapp" component={() =><MyApp process={...} />} />
<Router>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.