问题
I have a simple App that uses BrowserRouter
from 'react-router-dom' v4. I'm trying to access the location.pathname
property from within the <BrowserRouter/>
component, without avail:
class App extends Component{
render(){
return (
<BrowserRouter>
// How do I access this.props.location?
<div className={(this.props.location.pathnme === "/account") ? "bgnd-black" : "bgnd-white"} >
<Switch>
<Route path="/login" component={LoginPage}/>
<Route path="/success" component={LoginSuccess}/>
<Route path="/account" component={MyAccount}/>
...
<Route component={Error404}/>
</Switch>
</div>
</BrowserRouter>
);
}
}
I know that I can access the app's current path location through the child components with this.props.location.pathname
, but I need to access it from the parent component, just below <BrowserRouter/>
to run additional logic that doesn't pertain to child components. How can I get this location?
回答1:
You can also do it using withRouter
which has a similar result to putting the code in a render
parameter and avoids the need for a "fake" <Route/>
.
Essentially you put the JSX that needs to know the location in a component of its own, which is wrapped by withRouter
. This supplies the location to the component:
import { withRouter } from 'react-router-dom';
const Content = withRouter(props =>
<div className={(props.location.pathname === "/account") ? "backg...
...
</div>
);
Then you use that in your main router section:
class App extends Component{
render() {
return (
<BrowserRouter>
<Content/>
...
回答2:
After digging through their GitHub issues, I found the solution. I must render a <Route />
within <BrowserRouter />
and pass the rest of my app into its render()
function with history
as a parameter. Within the render function, I can find the app's location in history.location.pathname
.
class App extends Component{
render(){
return (
<BrowserRouter>
// We must add a parent <Route> and render its children while passing 'history' as parameter
<Route path={Paths.reserve} render={(history) =>
// Within render(), we can find it in history.location.pathname
<div className={(history.location.pathname === "/account") ? "background-black" : "background-white"} >
<Switch>
<Route path="/login" component={LoginPage}/>
<Route path="/success" component={LoginSuccess}/>
<Route path="/account" component={MyAccount}/>
...
<Route component={Error404}/>
</Switch>
</div>
}/>
}} />
</BrowserRouter>
);
}
}
This will update the history
parameter automatically, without having to re-render on componentDidMount()
or componentDidUpdate()
回答3:
You achieve what u have asked for by doing this
import AccessRoute from './AccessRoute'
class App extends Component{
render(){
return (
<BrowserRouter>
<AccessRoute>
<div className={(this.props.location.pathnme === "/account") ? "bgnd-black" : "bgnd-white"} >
<Switch>
<Route path="/login" component={LoginPage}/>
<Route path="/success" component={LoginSuccess}/>
<Route path="/account" component={MyAccount}/>
...
<Route component={Error404}/>
</Switch>
</div>
</AccessRoute>
</BrowserRouter>
);
}
}
AccessRoute.jsx
import React from 'react'
import {withRouter} from 'react-router';
class AccessRoute extends React.Component{
constructor(props){
super(props);
}
//If you want to find the location on mount use this
componentDidMount(){
console.log("the path name is ",this.props.location.pathname);
}
//If you want to find the location on change use this
componentDidUpdate(prevprops){
if(this.props.location.pathname!=prevprops.location.pathname){
console.log("the new path name is ",this.props.location.pathname);
}
}
render(){
return(
this.props.children
);
}
}
export default withRouter(AccessRoute)
来源:https://stackoverflow.com/questions/47298325/react-router-dom-getting-props-location-from-within-browserrouter-component