Reputation: 3310
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:
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.
Upvotes: 105
Views: 178319
Reputation: 28397
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
}
Upvotes: 178
Reputation: 154
If the above solution didn't work for you, you can use import { withRouter } from 'react-router-dom';
Using this you can export your child class as -
class MyApp extends Component{
// your code
}
export default withRouter(MyApp);
And your class with Router -
// your code
<Router>
...
<Route path="/myapp" component={MyApp} />
// or if you are sending additional fields
<Route path="/myapp" component={() =><MyApp process={...} />} />
<Router>
Upvotes: 6