react-router-dom:从 <BrowserRouter> 组件中获取 props.location
react-router-dom: getting props.location from within <BrowserRouter> component
我有一个简单的应用程序,它使用 'react-router-dom' v4 中的 BrowserRouter
。我试图从 <BrowserRouter/>
组件中访问 location.pathname
属性,但无济于事:
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>
);
}
}
我知道我可以通过 this.props.location.pathname
的子组件访问应用程序的当前路径位置,但我需要从父组件访问它,就在 <BrowserRouter/>
到 [=25= 下面] 与子组件无关的附加逻辑。我怎样才能得到这个位置?
这样做你就达到了你的要求
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)
在深入了解他们的 GitHub 问题后,我找到了解决方案。我必须在 <BrowserRouter />
中渲染一个 <Route />
并将我的应用程序的其余部分传递到它的 render()
函数中,并将 history
作为参数。在渲染函数中,我可以在 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>
);
}
}
这将自动更新 history
参数,无需在 componentDidMount()
或 componentDidUpdate()
上重新渲染
您也可以使用 withRouter
执行此操作,这与将代码放在 render
参数中具有类似的结果,并且避免了对 "fake" <Route/>
的需要。
本质上,你将需要知道位置的 JSX 放在它自己的组件中,由 withRouter
包装。这提供了组件的位置:
import { withRouter } from 'react-router-dom';
const Content = withRouter(props =>
<div className={(props.location.pathname === "/account") ? "backg...
...
</div>
);
然后在主路由器部分使用它:
class App extends Component{
render() {
return (
<BrowserRouter>
<Content/>
...
因为 react-router v5.1.0
你可以使用 useLocation
.
https://reactrouter.com/web/api/Hooks/uselocation
class App extends Component{
render(){
const location = useLocation();
return (
<div className={(location.pathname === "/account") ? "bgnd-black" : "bgnd-white"} >
//...
</div>
);
}
}
// ...
<BrowserRouter>
<App />
</BrowserRouter>
我有一个简单的应用程序,它使用 'react-router-dom' v4 中的 BrowserRouter
。我试图从 <BrowserRouter/>
组件中访问 location.pathname
属性,但无济于事:
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>
);
}
}
我知道我可以通过 this.props.location.pathname
的子组件访问应用程序的当前路径位置,但我需要从父组件访问它,就在 <BrowserRouter/>
到 [=25= 下面] 与子组件无关的附加逻辑。我怎样才能得到这个位置?
这样做你就达到了你的要求
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)
在深入了解他们的 GitHub 问题后,我找到了解决方案。我必须在 <BrowserRouter />
中渲染一个 <Route />
并将我的应用程序的其余部分传递到它的 render()
函数中,并将 history
作为参数。在渲染函数中,我可以在 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>
);
}
}
这将自动更新 history
参数,无需在 componentDidMount()
或 componentDidUpdate()
您也可以使用 withRouter
执行此操作,这与将代码放在 render
参数中具有类似的结果,并且避免了对 "fake" <Route/>
的需要。
本质上,你将需要知道位置的 JSX 放在它自己的组件中,由 withRouter
包装。这提供了组件的位置:
import { withRouter } from 'react-router-dom';
const Content = withRouter(props =>
<div className={(props.location.pathname === "/account") ? "backg...
...
</div>
);
然后在主路由器部分使用它:
class App extends Component{
render() {
return (
<BrowserRouter>
<Content/>
...
因为 react-router v5.1.0
你可以使用 useLocation
.
https://reactrouter.com/web/api/Hooks/uselocation
class App extends Component{
render(){
const location = useLocation();
return (
<div className={(location.pathname === "/account") ? "bgnd-black" : "bgnd-white"} >
//...
</div>
);
}
}
// ...
<BrowserRouter>
<App />
</BrowserRouter>