Harkirat Saluja
Harkirat Saluja

Reputation: 8114

State changes in reactjs?

I have following layout:-

enter image description here

So basically there is a banner on top and banner contains image, title and sub-title.

Next to banner there is categories bar on left, feeds in center and right navbar on the right.

Following is my current route:-

ReactDOM.render((
     <Router history={browserHistory}>
      <Route path="/" component={app}>
       <IndexRoute component={home}/>
       <Route path="/articles" component={articles} />
       <Route path="/articles/topics/:featureName" component={articleFeatures} />
       <Route path="/articles/:slug" component={articleContent}/>
       <Route path="interviews" component={interviews}>
          <Route path="interviews/:slug" component={interviewContent} />
       </Route>
       <Route path="collections" component={collections}>
          <Route path="collections/:slug" component={collection} />
       </Route>
  </Route>
  </Router>
), document.getElementById('app'));

Following is my app.js :-

class App extends React.Component{
   render(){
     return(
       <div className="insights">
          <Banner />
          <div className="content-container">
            <LeftNavBar/>
            <div className ="feeds">{this.props.children}</div>
            <RightNavbar/>
          </div>
      </div>
   )
 }
}

export default App;

So, as seen from above i have put Banner, LeftNavbar and RightNavBar components in App.jsx , so there components would stay same for childrens.

Now i want to change the contents of banner component i.e banner title,banner image and banner sub title for each page.

So my /articles/ would have different banner content and /articles/:slug would have different banner content.

So basically how do change the contents of banner component for different pages?

Upvotes: 0

Views: 108

Answers (1)

ctrlplusb
ctrlplusb

Reputation: 13137

You could use the named components feature of react-router.

For example you change the component prop to components and then set an object containing the named components:

import BannerA from './BannerA';
import BannerB from './BannerB';

ReactDOM.render((
     <Router history={browserHistory}>
      <Route path="/" component={app}>
       <IndexRoute components={{ main: home, banner: BannerA }}/>
       <Route path="/articles" components={{ main: articles, banner: BannerB } } />
       <Route path="/articles/topics/:featureName" components={{ main: articleFeatures, banner: BannerA }} />
       <Route path="/articles/:slug" components={{ main: articleContent, banner: BannerA }}/>
       <Route path="interviews" component={interviews}>
          <Route path="interviews/:slug" component={interviewContent} />
       </Route>
       <Route path="collections" component={collections}>
          <Route path="collections/:slug" component={collection} />
       </Route>
  </Route>
  </Router>
), document.getElementById('app'));

You will notice I specifically didn't add this change for all your routes, illustrating that you can still mix and match.

And then change your App to the following. I have set a default banner in case the router doesn't provide one, and if the main component isn't provided we fall back on the old this.props.children approach.

 import DefaultBanner from './DefaultBanner';  

 class App extends React.Component{
   render(){
     return(
       <div className="insights">
          {this.props.banner || <DefaultBanner /> }
          <div className="content-container">
            <LeftNavBar/>
            <div className ="feeds">
              {this.props.main || this.props.children}
            </div>
            <RightNavbar/>
          </div>
      </div>
   )
 }
}

Upvotes: 1

Related Questions