Search code examples
javascriptreactjsreact-router

react-router getting this.props.location in child components


As I understand <Route path="/" component={App} /> will give App routing-related props like location and params. If my App component has many nested child components, how do I allow a child component to have access to these props without:

  • passing props from App?
  • using window object?
  • creating routes for nested child components?

I thought this.context.router would have some information related to the routes, but this.context.router seems to have only some functions for manipulating the routes.


Solution

  • V6

    You can use useNavigate, useLocation and useMatch in your component to get matchPath, navigate and location .

    const Child = () => {
      const location = useLocation();
      const navigate = useNavigate();
      const match = useMatch("write-the-url-you-want-to-match-here");
    
      return (
        <div>{location.pathname}</div>
      )
    }
    
    export default Child
    

    V5.1 & Hooks (Requires React >= 16.8)

    You can use useHistory, useLocation and useRouteMatch in your component to get match, history and location .

    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

    You can use withRouter HOC in order to inject match, history and location in your component 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

    You can use withRouter HOC in order to inject router, params, location, routes in your component props.

    class Child extends React.Component {
    
      render() {
        const { router, params, location, routes } = this.props
    
        return (
          <div>{location.pathname}</div>
        )
      }
    }
    
    export default withRouter(Child)
    

    Original answer

    If you don't want to use the props, you can use the context as described in React Router documentation

    First, you have to set up your childContextTypes and getChildContext

    class App extends React.Component{
      
      getChildContext() {
        return {
          location: this.props.location
        }
      }
    
      render() {
        return <Child/>;
      }
    }
    
    App.childContextTypes = {
        location: React.PropTypes.object
    }
    

    Then, you will be able to access to the location object in your child components using the context like this

    class Child extends React.Component{
       
       render() {
         return (
           <div>{this.context.location.pathname}</div>
         )
       }
       
    }
    
    Child.contextTypes = {
        location: React.PropTypes.object
     }