我将此BrowserRouter组件作为顶层组件,并且标题字符串处于其状态。该组件将呈现一个NavigationComponent,该导航组件基本上是一个导航栏,在此我想设置一个标题,该标题会根据我在网站上的位置而变化。
该组件看起来大致是这样
changeTitle(title) {
this.setState({
title: title,
})
}
<BrowserRouter>
<div>
<NavigationComponent title={this.state.title}/>
<Switch>
<Route exact path="/" render={(props) => (
<App {...props} changeTitle= {this.changeTitle.bind(this)}/>
)} />
<Route exact path="/login" component={LoginComponent }/>
<Route exact path="/logout" component={LoginComponent }/>
</Switch>
</div>
</BrowserRouter>
现在,我知道如何向应用程序组件公开方法changeTitle
。
但是我想进一步公开该方法,而我在atm上实现的方法是这样的:
class App extends React.Component{
constructor(props){
super(props);
}
changeTitle(title) {
this.props.changeTitle(title);
}
render(){
return(
<OverviewComponent changeTitle= {this.changeTitle.bind(this)}/>
}
} // note: App component stripped down
在Overviewing组件中,这是我第一次真正调用changeTitle函数。
我的问题现在是:有没有更聪明的方法来实现此目标而无需将changeTitle方法传递给每个孩子?还有更多的组件在OverviewComponent之后被调用,这些组件也需要更改标题。
答案 0 :(得分:1)
在您的NavigationComponent中,我认为有一个事件侦听器会更有意义,该事件侦听器将在您导航到另一个页面时进行检查。
看来您已经在使用react-router-dom
,所以这很完美。
您需要使用withRouter
中的react-router-dom
HOC包装组件。这将使我们能够访问history
道具,该道具具有事件侦听器方法。我们可以在componentDidMount()中创建该事件侦听器,使其始终处于活动状态。
import { withRouter } from "react-router-dom"
class NavigationComponent extends React.Component{
state = {
title: "Home"
}
changeTitle = (newTitle) => {
this.setState({
title: newTitle
})
}
componentDidMount(){
//listens for any route changes
this.props.history.listen(() => {
this.changeTitle(window.location.pathname) <-- this can be whatever value you want.
})
}
render(){
<div>{this.state.title}</div>
}
}
export default withRouter(NavigationComponent)
这似乎比必须从另一个组件传递值要直观得多。
答案 1 :(得分:1)
选中window.location.pathname
并将路径名设置为导航栏标题
// Navbar.js
changeTitle = () => {
switch(window.location.pathname){
case '/profile':
return 'Profile';
case '/admin':
return 'Admin';
default:
return 'Dashboard';
}
}
render(){
let title = changeTitle();
return(<div>{title}</div>)
}