根据渲染的页面来响应更改导航栏标题

时间:2019-05-17 08:38:07

标签: reactjs

我将此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之后被调用,这些组件也需要更改标题。

2 个答案:

答案 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>)
}