Navbar with dynamic content and behaviour

2019-08-18 07:58发布

问题:

Say I have the following App.js:

App.js

  render() {
    return (
      <div>
        <Navbar />
        <Router>
          <Home path="/" />
          <RouteA path="/routeA" />
          <RouteB path="/routeB" /> 
        </Router>
      </div>
    );
  }

So I need the <Navbar /> to behave and look differently in the /routeA and /routeB.

For example, there is a back button in the <Navbar />. And when user is in /routeA, clicking the back btn will go back one step in history.

However, when user is in /routeB, not only that clicking back btn will now pops up an alert, we also need to render a component that has updating props inside the <Navbar />.

So the way I go about this is, well, redux: The <Navbar /> is connected to its own slice of state in the store. Then, in my routes, in order to make the navbar dynamic accordingly, I dispatch actions with my function and component to make the <Navbar /> behave and look the way I want. So far so good.

Problem is we can't serialize 'function' and 'component' objects in the store and subsequently localstorage...so like on refresh, they are gone...

So my workaround for the 'function' is I immediately dispatch it in the routes' constructor. Whereas for the 'component', I use Portal in my routes' render method to insert it to my <Navbar />...

My question is how would you implement this differently?

Thank you for reading!

回答1:

You can send function to route components and call this funciton when component is mounted, you can have functions defined inside NavBar component, and switch based on the page you are on.

updateLayout = (page) => {this.setState({currentPage: page})}
render() {
return (
  <div>
    <Navbar currentPage={this.state.currentPage} />
    <Router>
      <Home path="/" render={()=> <ComponentHome updateLayout={this.updateLayout}>} />
      <RouteA path="/routeA" render={()=> <ComponentA updateLayout={this.updateLayout}>} />
      <RouteB path="/routeB" render={()=> <ComponentB updateLayout={this.updateLayout}>} /> 
    </Router>
  </div>
);

}