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

javascript, react-router, reactjs

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
 }

Problem

As I understand `<Route path="/" component={App} />` will gives `App` routing-related props like `location` and `params`. If my `App` component has many nested child components, how do I get the 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 only have some functions to manipulate the routes.

Original source