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

IT技术 javascript reactjs react-router
2021-02-09 23:37:25

据我了解,<Route path="/" component={App} />将提供App与路由相关的props,如locationparams如果我的App组件有许多嵌套的子组件,我如何让子组件无需访问这些props:

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

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

2个回答

(更新) V5.1 & Hooks (需要 React >= 16.8)

您可以在组件中使用useHistory,useLocationuseRouteMatch来获取match,historylocation

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

您可以使用withRouterHOC 来注入match,historylocation在您的组件props中。

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 来在你的组件 props 中注入router, params, location, routes

class Child extends React.Component {

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

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

export default withRouter(Child)

原答案

如果你不想使用 props,你可以使用React Router 文档中描述的上下文

首先,您必须设置您的childContextTypesgetChildContext

class App extends React.Component{

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

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

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

然后,您将能够使用这样的上下文访问子组件中的位置对象

class Child extends React.Component{

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

}

Child.contextTypes = {
    location: React.PropTypes.object
 }
我是 React 的新手。因此,如果我错了,请原谅我,但是使用 有什么问题window.location.pathname
2021-03-16 23:37:25
window.location 是可变的,因此最好不要访问它,而是使用不可变的版本。另外,我认为可以使用与 window.location 不同的逻辑位置(至少在 nextjs 中是这样),因此可以从路由器获得与直接窗口历史记录不同的位置
2021-03-16 23:37:25
谢谢指点。我没有阅读文档的那部分。我以为只有context.router
2021-03-17 23:37:25
@ArturBarseghyanwindow如果 React 代码在服务器上运行,例如实现服务器端路由,则对象不存在。
2021-04-13 23:37:25

如果上述解决方案对您不起作用,您可以使用 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>